aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorSteffen Klassert <steffen.klassert@secunet.com>2014-02-21 02:41:10 -0500
committerSteffen Klassert <steffen.klassert@secunet.com>2014-02-25 01:04:18 -0500
commitdf3893c176e9b0bb39b28ab5ec8113fa20ad1ee0 (patch)
tree789c670133d5cbf000633d2be1416db3cd29da31 /net/ipv4
parent6d608f06e390d803c1d0e604cae280f1e708bf68 (diff)
vti: Update the ipv4 side to use it's own receive hook.
With this patch, vti uses the IPsec protocol multiplexer to register it's own receive side hooks for ESP, AH and IPCOMP. Vti now does the following on receive side: 1. Do an input policy check for the IPsec packet we received. This is required because this packet could be already prosecces by IPsec, so an inbuond policy check is needed. 2. Mark the packet with the i_key. The policy and the state must match this key now. Policy and state belong to the outer namespace and policy enforcement is done at the further layers. 3. Call the generic xfrm layer to do decryption and decapsulation. 4. Wait for a callback from the xfrm layer to properly clean the skb to not leak informations on namespace and to update the device statistics. On transmit side: 1. Mark the packet with the o_key. The policy and the state must match this key now. 2. Do a xfrm_lookup on the original packet with the mark applied. 3. Check if we got an IPsec route. 4. Clean the skb to not leak informations on namespace transitions. 5. Attach the dst_enty we got from the xfrm_lookup to the skb. 6. Call dst_output to do the IPsec processing. 7. Do the device statistics. Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_vti.c234
1 files changed, 187 insertions, 47 deletions
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 48eafae51769..b23f9e63b1cd 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -49,8 +49,8 @@ static struct rtnl_link_ops vti_link_ops __read_mostly;
49static int vti_net_id __read_mostly; 49static int vti_net_id __read_mostly;
50static int vti_tunnel_init(struct net_device *dev); 50static int vti_tunnel_init(struct net_device *dev);
51 51
52/* We dont digest the packet therefore let the packet pass */ 52static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi,
53static int vti_rcv(struct sk_buff *skb) 53 int encap_type)
54{ 54{
55 struct ip_tunnel *tunnel; 55 struct ip_tunnel *tunnel;
56 const struct iphdr *iph = ip_hdr(skb); 56 const struct iphdr *iph = ip_hdr(skb);
@@ -60,66 +60,98 @@ static int vti_rcv(struct sk_buff *skb)
60 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 60 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
61 iph->saddr, iph->daddr, 0); 61 iph->saddr, iph->daddr, 0);
62 if (tunnel != NULL) { 62 if (tunnel != NULL) {
63 struct pcpu_sw_netstats *tstats; 63 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
64 u32 oldmark = skb->mark; 64 goto drop;
65 int ret; 65
66 66 XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel;
67 67 skb->mark = be32_to_cpu(tunnel->parms.i_key);
68 /* temporarily mark the skb with the tunnel o_key, to 68
69 * only match policies with this mark. 69 return xfrm_input(skb, nexthdr, spi, encap_type);
70 */ 70 }
71 skb->mark = be32_to_cpu(tunnel->parms.o_key); 71
72 ret = xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb); 72 return -EINVAL;
73 skb->mark = oldmark; 73drop:
74 if (!ret) 74 kfree_skb(skb);
75 return -1; 75 return 0;
76 76}
77 tstats = this_cpu_ptr(tunnel->dev->tstats); 77
78 u64_stats_update_begin(&tstats->syncp); 78static int vti_rcv(struct sk_buff *skb)
79 tstats->rx_packets++; 79{
80 tstats->rx_bytes += skb->len; 80 XFRM_SPI_SKB_CB(skb)->family = AF_INET;
81 u64_stats_update_end(&tstats->syncp); 81 XFRM_SPI_SKB_CB(skb)->daddroff = offsetof(struct iphdr, daddr);
82 82
83 secpath_reset(skb); 83 return vti_input(skb, ip_hdr(skb)->protocol, 0, 0);
84 skb->dev = tunnel->dev; 84}
85
86static int vti_rcv_cb(struct sk_buff *skb, int err)
87{
88 unsigned short family;
89 struct net_device *dev;
90 struct pcpu_sw_netstats *tstats;
91 struct xfrm_state *x;
92 struct ip_tunnel *tunnel = XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4;
93
94 if (!tunnel)
85 return 1; 95 return 1;
96
97 dev = tunnel->dev;
98
99 if (err) {
100 dev->stats.rx_errors++;
101 dev->stats.rx_dropped++;
102
103 return 0;
86 } 104 }
87 105
88 return -1; 106 x = xfrm_input_state(skb);
107 family = x->inner_mode->afinfo->family;
108
109 if (!xfrm_policy_check(NULL, XFRM_POLICY_IN, skb, family))
110 return -EPERM;
111
112 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(skb->dev)));
113 skb->dev = dev;
114
115 tstats = this_cpu_ptr(dev->tstats);
116
117 u64_stats_update_begin(&tstats->syncp);
118 tstats->rx_packets++;
119 tstats->rx_bytes += skb->len;
120 u64_stats_update_end(&tstats->syncp);
121
122 return 0;
89} 123}
90 124
91/* This function assumes it is being called from dev_queue_xmit() 125/* This function assumes it is being called from dev_queue_xmit()
92 * and that skb is filled properly by that function. 126 * and that skb is filled properly by that function.
93 */ 127 */
94
95static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 128static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
96{ 129{
97 struct ip_tunnel *tunnel = netdev_priv(dev); 130 struct ip_tunnel *tunnel = netdev_priv(dev);
98 struct iphdr *tiph = &tunnel->parms.iph;
99 u8 tos;
100 struct rtable *rt; /* Route to the other host */ 131 struct rtable *rt; /* Route to the other host */
101 struct net_device *tdev; /* Device to other host */ 132 struct net_device *tdev; /* Device to other host */
102 struct iphdr *old_iph = ip_hdr(skb); 133 struct flowi fl;
103 __be32 dst = tiph->daddr;
104 struct flowi4 fl4;
105 int err; 134 int err;
106 135
107 if (skb->protocol != htons(ETH_P_IP)) 136 if (skb->protocol != htons(ETH_P_IP))
108 goto tx_error; 137 goto tx_error;
109 138
110 tos = old_iph->tos; 139 memset(&fl, 0, sizeof(fl));
140 skb->mark = be32_to_cpu(tunnel->parms.o_key);
141 xfrm_decode_session(skb, &fl, AF_INET);
142
143 if (!skb_dst(skb)) {
144 dev->stats.tx_carrier_errors++;
145 goto tx_error_icmp;
146 }
111 147
112 memset(&fl4, 0, sizeof(fl4)); 148 dst_hold(skb_dst(skb));
113 flowi4_init_output(&fl4, tunnel->parms.link, 149 rt = (struct rtable *)xfrm_lookup(tunnel->net, skb_dst(skb), &fl, NULL, 0);
114 be32_to_cpu(tunnel->parms.o_key), RT_TOS(tos),
115 RT_SCOPE_UNIVERSE,
116 IPPROTO_IPIP, 0,
117 dst, tiph->saddr, 0, 0);
118 rt = ip_route_output_key(dev_net(dev), &fl4);
119 if (IS_ERR(rt)) { 150 if (IS_ERR(rt)) {
120 dev->stats.tx_carrier_errors++; 151 dev->stats.tx_carrier_errors++;
121 goto tx_error_icmp; 152 goto tx_error_icmp;
122 } 153 }
154
123 /* if there is no transform then this tunnel is not functional. 155 /* if there is no transform then this tunnel is not functional.
124 * Or if the xfrm is not mode tunnel. 156 * Or if the xfrm is not mode tunnel.
125 */ 157 */
@@ -147,9 +179,8 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
147 } 179 }
148 180
149 memset(IPCB(skb), 0, sizeof(*IPCB(skb))); 181 memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
150 skb_dst_drop(skb); 182 skb_scrub_packet(skb, !net_eq(tunnel->net, dev_net(dev)));
151 skb_dst_set(skb, &rt->dst); 183 skb_dst_set(skb, &rt->dst);
152 nf_reset(skb);
153 skb->dev = skb_dst(skb)->dev; 184 skb->dev = skb_dst(skb)->dev;
154 185
155 err = dst_output(skb); 186 err = dst_output(skb);
@@ -166,6 +197,65 @@ tx_error:
166 return NETDEV_TX_OK; 197 return NETDEV_TX_OK;
167} 198}
168 199
200static int vti4_err(struct sk_buff *skb, u32 info)
201{
202 __be32 spi;
203 struct xfrm_state *x;
204 struct ip_tunnel *tunnel;
205 struct ip_esp_hdr *esph;
206 struct ip_auth_hdr *ah ;
207 struct ip_comp_hdr *ipch;
208 struct net *net = dev_net(skb->dev);
209 const struct iphdr *iph = (const struct iphdr *)skb->data;
210 int protocol = iph->protocol;
211 struct ip_tunnel_net *itn = net_generic(net, vti_net_id);
212
213 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
214 iph->daddr, iph->saddr, 0);
215 if (!tunnel)
216 return -1;
217
218 switch (protocol) {
219 case IPPROTO_ESP:
220 esph = (struct ip_esp_hdr *)(skb->data+(iph->ihl<<2));
221 spi = esph->spi;
222 break;
223 case IPPROTO_AH:
224 ah = (struct ip_auth_hdr *)(skb->data+(iph->ihl<<2));
225 spi = ah->spi;
226 break;
227 case IPPROTO_COMP:
228 ipch = (struct ip_comp_hdr *)(skb->data+(iph->ihl<<2));
229 spi = htonl(ntohs(ipch->cpi));
230 break;
231 default:
232 return 0;
233 }
234
235 switch (icmp_hdr(skb)->type) {
236 case ICMP_DEST_UNREACH:
237 if (icmp_hdr(skb)->code != ICMP_FRAG_NEEDED)
238 return 0;
239 case ICMP_REDIRECT:
240 break;
241 default:
242 return 0;
243 }
244
245 x = xfrm_state_lookup(net, skb->mark, (const xfrm_address_t *)&iph->daddr,
246 spi, protocol, AF_INET);
247 if (!x)
248 return 0;
249
250 if (icmp_hdr(skb)->type == ICMP_DEST_UNREACH)
251 ipv4_update_pmtu(skb, net, info, 0, 0, protocol, 0);
252 else
253 ipv4_redirect(skb, net, 0, 0, protocol, 0);
254 xfrm_state_put(x);
255
256 return 0;
257}
258
169static int 259static int
170vti_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 260vti_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
171{ 261{
@@ -181,12 +271,13 @@ vti_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
181 return -EINVAL; 271 return -EINVAL;
182 } 272 }
183 273
274 p.i_flags |= VTI_ISVTI;
184 err = ip_tunnel_ioctl(dev, &p, cmd); 275 err = ip_tunnel_ioctl(dev, &p, cmd);
185 if (err) 276 if (err)
186 return err; 277 return err;
187 278
188 if (cmd != SIOCDELTUNNEL) { 279 if (cmd != SIOCDELTUNNEL) {
189 p.i_flags |= GRE_KEY | VTI_ISVTI; 280 p.i_flags |= GRE_KEY;
190 p.o_flags |= GRE_KEY; 281 p.o_flags |= GRE_KEY;
191 } 282 }
192 283
@@ -241,9 +332,28 @@ static void __net_init vti_fb_tunnel_init(struct net_device *dev)
241 iph->ihl = 5; 332 iph->ihl = 5;
242} 333}
243 334
244static struct xfrm_tunnel_notifier vti_handler __read_mostly = { 335static struct xfrm4_protocol vti_esp4_protocol __read_mostly = {
245 .handler = vti_rcv, 336 .handler = vti_rcv,
246 .priority = 1, 337 .input_handler = vti_input,
338 .cb_handler = vti_rcv_cb,
339 .err_handler = vti4_err,
340 .priority = 100,
341};
342
343static struct xfrm4_protocol vti_ah4_protocol __read_mostly = {
344 .handler = vti_rcv,
345 .input_handler = vti_input,
346 .cb_handler = vti_rcv_cb,
347 .err_handler = vti4_err,
348 .priority = 100,
349};
350
351static struct xfrm4_protocol vti_ipcomp4_protocol __read_mostly = {
352 .handler = vti_rcv,
353 .input_handler = vti_input,
354 .cb_handler = vti_rcv_cb,
355 .err_handler = vti4_err,
356 .priority = 100,
247}; 357};
248 358
249static int __net_init vti_init_net(struct net *net) 359static int __net_init vti_init_net(struct net *net)
@@ -287,6 +397,8 @@ static void vti_netlink_parms(struct nlattr *data[],
287 if (!data) 397 if (!data)
288 return; 398 return;
289 399
400 parms->i_flags = VTI_ISVTI;
401
290 if (data[IFLA_VTI_LINK]) 402 if (data[IFLA_VTI_LINK])
291 parms->link = nla_get_u32(data[IFLA_VTI_LINK]); 403 parms->link = nla_get_u32(data[IFLA_VTI_LINK]);
292 404
@@ -382,10 +494,31 @@ static int __init vti_init(void)
382 err = register_pernet_device(&vti_net_ops); 494 err = register_pernet_device(&vti_net_ops);
383 if (err < 0) 495 if (err < 0)
384 return err; 496 return err;
385 err = xfrm4_mode_tunnel_input_register(&vti_handler); 497 err = xfrm4_protocol_register(&vti_esp4_protocol, IPPROTO_ESP);
498 if (err < 0) {
499 unregister_pernet_device(&vti_net_ops);
500 pr_info("vti init: can't register tunnel\n");
501
502 return err;
503 }
504
505 err = xfrm4_protocol_register(&vti_ah4_protocol, IPPROTO_AH);
506 if (err < 0) {
507 xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
508 unregister_pernet_device(&vti_net_ops);
509 pr_info("vti init: can't register tunnel\n");
510
511 return err;
512 }
513
514 err = xfrm4_protocol_register(&vti_ipcomp4_protocol, IPPROTO_COMP);
386 if (err < 0) { 515 if (err < 0) {
516 xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
517 xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
387 unregister_pernet_device(&vti_net_ops); 518 unregister_pernet_device(&vti_net_ops);
388 pr_info("vti init: can't register tunnel\n"); 519 pr_info("vti init: can't register tunnel\n");
520
521 return err;
389 } 522 }
390 523
391 err = rtnl_link_register(&vti_link_ops); 524 err = rtnl_link_register(&vti_link_ops);
@@ -395,7 +528,9 @@ static int __init vti_init(void)
395 return err; 528 return err;
396 529
397rtnl_link_failed: 530rtnl_link_failed:
398 xfrm4_mode_tunnel_input_deregister(&vti_handler); 531 xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
532 xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
533 xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
399 unregister_pernet_device(&vti_net_ops); 534 unregister_pernet_device(&vti_net_ops);
400 return err; 535 return err;
401} 536}
@@ -403,8 +538,13 @@ rtnl_link_failed:
403static void __exit vti_fini(void) 538static void __exit vti_fini(void)
404{ 539{
405 rtnl_link_unregister(&vti_link_ops); 540 rtnl_link_unregister(&vti_link_ops);
406 if (xfrm4_mode_tunnel_input_deregister(&vti_handler)) 541 if (xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP))
542 pr_info("vti close: can't deregister tunnel\n");
543 if (xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH))
407 pr_info("vti close: can't deregister tunnel\n"); 544 pr_info("vti close: can't deregister tunnel\n");
545 if (xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP))
546 pr_info("vti close: can't deregister tunnel\n");
547
408 548
409 unregister_pernet_device(&vti_net_ops); 549 unregister_pernet_device(&vti_net_ops);
410} 550}