aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorDavid Ahern <dsa@cumulusnetworks.com>2016-05-10 14:19:50 -0400
committerDavid S. Miller <davem@davemloft.net>2016-05-11 19:31:40 -0400
commit74b20582ac389ee9f18a6fcc0eef244658ce8de0 (patch)
tree63f32ea105bb23a61a15c91615ef5cf8895e7bd7 /include/net
parentca4aa976f04d14bc7da60dce0e2afc34c9f0f1d2 (diff)
net: l3mdev: Add hook in ip and ipv6
Currently the VRF driver uses the rx_handler to switch the skb device to the VRF device. Switching the dev prior to the ip / ipv6 layer means the VRF driver has to duplicate IP/IPv6 processing which adds overhead and makes features such as retaining the ingress device index more complicated than necessary. This patch moves the hook to the L3 layer just after the first NF_HOOK for PRE_ROUTING. This location makes exposing the original ingress device trivial (next patch) and allows adding other NF_HOOKs to the VRF driver in the future. dev_queue_xmit_nit is exported so that the VRF driver can cycle the skb with the switched device through the packet taps to maintain current behavior (tcpdump can be used on either the vrf device or the enslaved devices). Signed-off-by: David Ahern <dsa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r--include/net/l3mdev.h42
-rw-r--r--include/net/tcp.h4
2 files changed, 45 insertions, 1 deletions
diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h
index 78872bd1dc2c..374388dc01c8 100644
--- a/include/net/l3mdev.h
+++ b/include/net/l3mdev.h
@@ -25,6 +25,8 @@
25 25
26struct l3mdev_ops { 26struct l3mdev_ops {
27 u32 (*l3mdev_fib_table)(const struct net_device *dev); 27 u32 (*l3mdev_fib_table)(const struct net_device *dev);
28 struct sk_buff * (*l3mdev_l3_rcv)(struct net_device *dev,
29 struct sk_buff *skb, u16 proto);
28 30
29 /* IPv4 ops */ 31 /* IPv4 ops */
30 struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev, 32 struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev,
@@ -134,6 +136,34 @@ int l3mdev_get_saddr(struct net *net, int ifindex, struct flowi4 *fl4);
134 136
135struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6); 137struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6);
136 138
139static inline
140struct sk_buff *l3mdev_l3_rcv(struct sk_buff *skb, u16 proto)
141{
142 struct net_device *master = NULL;
143
144 if (netif_is_l3_slave(skb->dev))
145 master = netdev_master_upper_dev_get_rcu(skb->dev);
146 else if (netif_is_l3_master(skb->dev))
147 master = skb->dev;
148
149 if (master && master->l3mdev_ops->l3mdev_l3_rcv)
150 skb = master->l3mdev_ops->l3mdev_l3_rcv(master, skb, proto);
151
152 return skb;
153}
154
155static inline
156struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
157{
158 return l3mdev_l3_rcv(skb, AF_INET);
159}
160
161static inline
162struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
163{
164 return l3mdev_l3_rcv(skb, AF_INET6);
165}
166
137#else 167#else
138 168
139static inline int l3mdev_master_ifindex_rcu(const struct net_device *dev) 169static inline int l3mdev_master_ifindex_rcu(const struct net_device *dev)
@@ -194,6 +224,18 @@ struct dst_entry *l3mdev_get_rt6_dst(struct net *net, const struct flowi6 *fl6)
194{ 224{
195 return NULL; 225 return NULL;
196} 226}
227
228static inline
229struct sk_buff *l3mdev_ip_rcv(struct sk_buff *skb)
230{
231 return skb;
232}
233
234static inline
235struct sk_buff *l3mdev_ip6_rcv(struct sk_buff *skb)
236{
237 return skb;
238}
197#endif 239#endif
198 240
199#endif /* _NET_L3MDEV_H_ */ 241#endif /* _NET_L3MDEV_H_ */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index c9ab561387c4..0bcc70f4e1fb 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -786,7 +786,9 @@ struct tcp_skb_cb {
786 */ 786 */
787static inline int tcp_v6_iif(const struct sk_buff *skb) 787static inline int tcp_v6_iif(const struct sk_buff *skb)
788{ 788{
789 return TCP_SKB_CB(skb)->header.h6.iif; 789 bool l3_slave = skb_l3mdev_slave(TCP_SKB_CB(skb)->header.h6.flags);
790
791 return l3_slave ? skb->skb_iif : TCP_SKB_CB(skb)->header.h6.iif;
790} 792}
791#endif 793#endif
792 794