Skip to content

Commit 3d9dc40

Browse files
committed
net: Revert vrf-local changes.
This reverts commit 2fb7ea4. It results in build errors because ip6_input is not a symbol exported to modules. Signed-off-by: David S. Miller <[email protected]>
1 parent 2fb7ea4 commit 3d9dc40

File tree

1 file changed

+33
-201
lines changed

1 file changed

+33
-201
lines changed

drivers/net/vrf.c

Lines changed: 33 additions & 201 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,7 @@
4444

4545
struct net_vrf {
4646
struct rtable __rcu *rth;
47-
struct rtable __rcu *rth_local;
4847
struct rt6_info __rcu *rt6;
49-
struct rt6_info __rcu *rt6_local;
5048
u32 tb_id;
5149
};
5250

@@ -56,20 +54,9 @@ struct pcpu_dstats {
5654
u64 tx_drps;
5755
u64 rx_pkts;
5856
u64 rx_bytes;
59-
u64 rx_drps;
6057
struct u64_stats_sync syncp;
6158
};
6259

63-
static void vrf_rx_stats(struct net_device *dev, int len)
64-
{
65-
struct pcpu_dstats *dstats = this_cpu_ptr(dev->dstats);
66-
67-
u64_stats_update_begin(&dstats->syncp);
68-
dstats->rx_pkts++;
69-
dstats->rx_bytes += len;
70-
u64_stats_update_end(&dstats->syncp);
71-
}
72-
7360
static void vrf_tx_error(struct net_device *vrf_dev, struct sk_buff *skb)
7461
{
7562
vrf_dev->stats.tx_errors++;
@@ -104,34 +91,6 @@ static struct rtnl_link_stats64 *vrf_get_stats64(struct net_device *dev,
10491
return stats;
10592
}
10693

107-
/* Local traffic destined to local address. Reinsert the packet to rx
108-
* path, similar to loopback handling.
109-
*/
110-
static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev,
111-
struct dst_entry *dst)
112-
{
113-
int len = skb->len;
114-
115-
skb_orphan(skb);
116-
117-
skb_dst_set(skb, dst);
118-
skb_dst_force(skb);
119-
120-
/* set pkt_type to avoid skb hitting packet taps twice -
121-
* once on Tx and again in Rx processing
122-
*/
123-
skb->pkt_type = PACKET_LOOPBACK;
124-
125-
skb->protocol = eth_type_trans(skb, dev);
126-
127-
if (likely(netif_rx(skb) == NET_RX_SUCCESS))
128-
vrf_rx_stats(dev, len);
129-
else
130-
this_cpu_inc(dev->dstats->rx_drps);
131-
132-
return NETDEV_TX_OK;
133-
}
134-
13594
#if IS_ENABLED(CONFIG_IPV6)
13695
static netdev_tx_t vrf_process_v6_outbound(struct sk_buff *skb,
13796
struct net_device *dev)
@@ -158,51 +117,8 @@ static netdev_tx_t vrf_process_v6_outbound(struct sk_buff *skb,
158117
goto err;
159118

160119
skb_dst_drop(skb);
161-
162-
/* if dst.dev is loopback or the VRF device again this is locally
163-
* originated traffic destined to a local address. Short circuit
164-
* to Rx path using our local dst
165-
*/
166-
if (dst->dev == net->loopback_dev || dst->dev == dev) {
167-
struct net_vrf *vrf = netdev_priv(dev);
168-
struct rt6_info *rt6_local;
169-
170-
/* release looked up dst and use cached local dst */
171-
dst_release(dst);
172-
173-
rcu_read_lock();
174-
175-
rt6_local = rcu_dereference(vrf->rt6_local);
176-
if (unlikely(!rt6_local)) {
177-
rcu_read_unlock();
178-
goto err;
179-
}
180-
181-
/* Ordering issue: cached local dst is created on newlink
182-
* before the IPv6 initialization. Using the local dst
183-
* requires rt6i_idev to be set so make sure it is.
184-
*/
185-
if (unlikely(!rt6_local->rt6i_idev)) {
186-
rt6_local->rt6i_idev = in6_dev_get(dev);
187-
if (!rt6_local->rt6i_idev) {
188-
rcu_read_unlock();
189-
goto err;
190-
}
191-
}
192-
193-
dst = &rt6_local->dst;
194-
dst_hold(dst);
195-
196-
rcu_read_unlock();
197-
198-
return vrf_local_xmit(skb, dev, &rt6_local->dst);
199-
}
200-
201120
skb_dst_set(skb, dst);
202121

203-
/* strip the ethernet header added for pass through VRF device */
204-
__skb_pull(skb, skb_network_offset(skb));
205-
206122
ret = ip6_local_out(net, skb->sk, skb);
207123
if (unlikely(net_xmit_eval(ret)))
208124
dev->stats.tx_errors++;
@@ -223,6 +139,29 @@ static netdev_tx_t vrf_process_v6_outbound(struct sk_buff *skb,
223139
}
224140
#endif
225141

142+
static int vrf_send_v4_prep(struct sk_buff *skb, struct flowi4 *fl4,
143+
struct net_device *vrf_dev)
144+
{
145+
struct rtable *rt;
146+
int err = 1;
147+
148+
rt = ip_route_output_flow(dev_net(vrf_dev), fl4, NULL);
149+
if (IS_ERR(rt))
150+
goto out;
151+
152+
/* TO-DO: what about broadcast ? */
153+
if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) {
154+
ip_rt_put(rt);
155+
goto out;
156+
}
157+
158+
skb_dst_drop(skb);
159+
skb_dst_set(skb, &rt->dst);
160+
err = 0;
161+
out:
162+
return err;
163+
}
164+
226165
static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb,
227166
struct net_device *vrf_dev)
228167
{
@@ -237,51 +176,9 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb,
237176
FLOWI_FLAG_SKIP_NH_OIF,
238177
.daddr = ip4h->daddr,
239178
};
240-
struct net *net = dev_net(vrf_dev);
241-
struct rtable *rt;
242-
243-
rt = ip_route_output_flow(net, &fl4, NULL);
244-
if (IS_ERR(rt))
245-
goto err;
246179

247-
if (rt->rt_type != RTN_UNICAST && rt->rt_type != RTN_LOCAL) {
248-
ip_rt_put(rt);
180+
if (vrf_send_v4_prep(skb, &fl4, vrf_dev))
249181
goto err;
250-
}
251-
252-
skb_dst_drop(skb);
253-
254-
/* if dst.dev is loopback or the VRF device again this is locally
255-
* originated traffic destined to a local address. Short circuit
256-
* to Rx path using our local dst
257-
*/
258-
if (rt->dst.dev == net->loopback_dev || rt->dst.dev == vrf_dev) {
259-
struct net_vrf *vrf = netdev_priv(vrf_dev);
260-
struct rtable *rth_local;
261-
struct dst_entry *dst = NULL;
262-
263-
ip_rt_put(rt);
264-
265-
rcu_read_lock();
266-
267-
rth_local = rcu_dereference(vrf->rth_local);
268-
if (likely(rth_local)) {
269-
dst = &rth_local->dst;
270-
dst_hold(dst);
271-
}
272-
273-
rcu_read_unlock();
274-
275-
if (unlikely(!dst))
276-
goto err;
277-
278-
return vrf_local_xmit(skb, vrf_dev, dst);
279-
}
280-
281-
skb_dst_set(skb, &rt->dst);
282-
283-
/* strip the ethernet header added for pass through VRF device */
284-
__skb_pull(skb, skb_network_offset(skb));
285182

286183
if (!ip4h->saddr) {
287184
ip4h->saddr = inet_select_addr(skb_dst(skb)->dev, 0,
@@ -303,6 +200,9 @@ static netdev_tx_t vrf_process_v4_outbound(struct sk_buff *skb,
303200

304201
static netdev_tx_t is_ip_tx_frame(struct sk_buff *skb, struct net_device *dev)
305202
{
203+
/* strip the ethernet header added for pass through VRF device */
204+
__skb_pull(skb, skb_network_offset(skb));
205+
306206
switch (skb->protocol) {
307207
case htons(ETH_P_IP):
308208
return vrf_process_v4_outbound(skb, dev);
@@ -377,64 +277,35 @@ static int vrf_output6(struct net *net, struct sock *sk, struct sk_buff *skb)
377277
static void vrf_rt6_release(struct net_vrf *vrf)
378278
{
379279
struct rt6_info *rt6 = rtnl_dereference(vrf->rt6);
380-
struct rt6_info *rt6_local = rtnl_dereference(vrf->rt6_local);
381280

382-
RCU_INIT_POINTER(vrf->rt6, NULL);
383-
RCU_INIT_POINTER(vrf->rt6_local, NULL);
384-
synchronize_rcu();
281+
rcu_assign_pointer(vrf->rt6, NULL);
385282

386283
if (rt6)
387284
dst_release(&rt6->dst);
388-
389-
if (rt6_local) {
390-
if (rt6_local->rt6i_idev)
391-
in6_dev_put(rt6_local->rt6i_idev);
392-
393-
dst_release(&rt6_local->dst);
394-
}
395285
}
396286

397287
static int vrf_rt6_create(struct net_device *dev)
398288
{
399-
int flags = DST_HOST | DST_NOPOLICY | DST_NOXFRM | DST_NOCACHE;
400289
struct net_vrf *vrf = netdev_priv(dev);
401290
struct net *net = dev_net(dev);
402291
struct fib6_table *rt6i_table;
403-
struct rt6_info *rt6, *rt6_local;
292+
struct rt6_info *rt6;
404293
int rc = -ENOMEM;
405294

406295
rt6i_table = fib6_new_table(net, vrf->tb_id);
407296
if (!rt6i_table)
408297
goto out;
409298

410-
/* create a dst for routing packets out a VRF device */
411-
rt6 = ip6_dst_alloc(net, dev, flags);
299+
rt6 = ip6_dst_alloc(net, dev,
300+
DST_HOST | DST_NOPOLICY | DST_NOXFRM | DST_NOCACHE);
412301
if (!rt6)
413302
goto out;
414303

415304
dst_hold(&rt6->dst);
416305

417306
rt6->rt6i_table = rt6i_table;
418307
rt6->dst.output = vrf_output6;
419-
420-
/* create a dst for local routing - packets sent locally
421-
* to local address via the VRF device as a loopback
422-
*/
423-
rt6_local = ip6_dst_alloc(net, dev, flags);
424-
if (!rt6_local) {
425-
dst_release(&rt6->dst);
426-
goto out;
427-
}
428-
429-
dst_hold(&rt6_local->dst);
430-
431-
rt6_local->rt6i_idev = in6_dev_get(dev);
432-
rt6_local->rt6i_flags = RTF_UP | RTF_NONEXTHOP | RTF_LOCAL;
433-
rt6_local->rt6i_table = rt6i_table;
434-
rt6_local->dst.input = ip6_input;
435-
436308
rcu_assign_pointer(vrf->rt6, rt6);
437-
rcu_assign_pointer(vrf->rt6_local, rt6_local);
438309

439310
rc = 0;
440311
out:
@@ -513,48 +384,29 @@ static int vrf_output(struct net *net, struct sock *sk, struct sk_buff *skb)
513384
static void vrf_rtable_release(struct net_vrf *vrf)
514385
{
515386
struct rtable *rth = rtnl_dereference(vrf->rth);
516-
struct rtable *rth_local = rtnl_dereference(vrf->rth_local);
517387

518-
RCU_INIT_POINTER(vrf->rth, NULL);
519-
RCU_INIT_POINTER(vrf->rth_local, NULL);
520-
synchronize_rcu();
388+
rcu_assign_pointer(vrf->rth, NULL);
521389

522390
if (rth)
523391
dst_release(&rth->dst);
524-
525-
if (rth_local)
526-
dst_release(&rth_local->dst);
527392
}
528393

529394
static int vrf_rtable_create(struct net_device *dev)
530395
{
531396
struct net_vrf *vrf = netdev_priv(dev);
532-
struct rtable *rth, *rth_local;
397+
struct rtable *rth;
533398

534399
if (!fib_new_table(dev_net(dev), vrf->tb_id))
535400
return -ENOMEM;
536401

537-
/* create a dst for routing packets out through a VRF device */
538402
rth = rt_dst_alloc(dev, 0, RTN_UNICAST, 1, 1, 0);
539403
if (!rth)
540404
return -ENOMEM;
541405

542-
/* create a dst for local ingress routing - packets sent locally
543-
* to local address via the VRF device as a loopback
544-
*/
545-
rth_local = rt_dst_alloc(dev, RTCF_LOCAL, RTN_LOCAL, 1, 1, 0);
546-
if (!rth_local) {
547-
dst_release(&rth->dst);
548-
return -ENOMEM;
549-
}
550-
551406
rth->dst.output = vrf_output;
552407
rth->rt_table_id = vrf->tb_id;
553408

554-
rth_local->rt_table_id = vrf->tb_id;
555-
556409
rcu_assign_pointer(vrf->rth, rth);
557-
rcu_assign_pointer(vrf->rth_local, rth_local);
558410

559411
return 0;
560412
}
@@ -780,16 +632,6 @@ static bool ipv6_ndisc_frame(const struct sk_buff *skb)
780632
static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
781633
struct sk_buff *skb)
782634
{
783-
/* loopback traffic; do not push through packet taps again.
784-
* Reset pkt_type for upper layers to process skb
785-
*/
786-
if (skb->pkt_type == PACKET_LOOPBACK) {
787-
skb->dev = vrf_dev;
788-
skb->skb_iif = vrf_dev->ifindex;
789-
skb->pkt_type = PACKET_HOST;
790-
goto out;
791-
}
792-
793635
/* if packet is NDISC keep the ingress interface */
794636
if (!ipv6_ndisc_frame(skb)) {
795637
skb->dev = vrf_dev;
@@ -802,7 +644,6 @@ static struct sk_buff *vrf_ip6_rcv(struct net_device *vrf_dev,
802644
IP6CB(skb)->flags |= IP6SKB_L3SLAVE;
803645
}
804646

805-
out:
806647
return skb;
807648
}
808649

@@ -820,19 +661,10 @@ static struct sk_buff *vrf_ip_rcv(struct net_device *vrf_dev,
820661
skb->dev = vrf_dev;
821662
skb->skb_iif = vrf_dev->ifindex;
822663

823-
/* loopback traffic; do not push through packet taps again.
824-
* Reset pkt_type for upper layers to process skb
825-
*/
826-
if (skb->pkt_type == PACKET_LOOPBACK) {
827-
skb->pkt_type = PACKET_HOST;
828-
goto out;
829-
}
830-
831664
skb_push(skb, skb->mac_len);
832665
dev_queue_xmit_nit(skb, vrf_dev);
833666
skb_pull(skb, skb->mac_len);
834667

835-
out:
836668
return skb;
837669
}
838670

0 commit comments

Comments
 (0)