aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Horman <simon.horman@netronome.com>2016-07-07 01:56:14 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-09 17:45:56 -0400
commit1b69e7e6c4da1e84edc2496fa91db289e5e493b0 (patch)
tree870c7db25c5e6f06d0c3fd7857b33ad65d095abb
parent49dbe7ae2168b3a933ecea1118fc0515c186bd64 (diff)
ipip: support MPLS over IPv4
Extend the IPIP driver to support MPLS over IPv4. The implementation is an extension of existing support for IPv4 over IPv4 and is based of multiple inner-protocol support for the SIT driver. Signed-off-by: Simon Horman <simon.horman@netronome.com> Reviewed-by: Dinan Gunawardena <dinan.gunawardena@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/ipip.c137
1 files changed, 121 insertions, 16 deletions
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 978370132f29..4ae3f8e6c6cc 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -148,14 +148,14 @@ static int ipip_err(struct sk_buff *skb, u32 info)
148 148
149 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) { 149 if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
150 ipv4_update_pmtu(skb, dev_net(skb->dev), info, 150 ipv4_update_pmtu(skb, dev_net(skb->dev), info,
151 t->parms.link, 0, IPPROTO_IPIP, 0); 151 t->parms.link, 0, iph->protocol, 0);
152 err = 0; 152 err = 0;
153 goto out; 153 goto out;
154 } 154 }
155 155
156 if (type == ICMP_REDIRECT) { 156 if (type == ICMP_REDIRECT) {
157 ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0, 157 ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
158 IPPROTO_IPIP, 0); 158 iph->protocol, 0);
159 err = 0; 159 err = 0;
160 goto out; 160 goto out;
161 } 161 }
@@ -177,12 +177,19 @@ out:
177 return err; 177 return err;
178} 178}
179 179
180static const struct tnl_ptk_info tpi = { 180static const struct tnl_ptk_info ipip_tpi = {
181 /* no tunnel info required for ipip. */ 181 /* no tunnel info required for ipip. */
182 .proto = htons(ETH_P_IP), 182 .proto = htons(ETH_P_IP),
183}; 183};
184 184
185static int ipip_rcv(struct sk_buff *skb) 185#if IS_ENABLED(CONFIG_MPLS)
186static const struct tnl_ptk_info mplsip_tpi = {
187 /* no tunnel info required for mplsip. */
188 .proto = htons(ETH_P_MPLS_UC),
189};
190#endif
191
192static int ipip_tunnel_rcv(struct sk_buff *skb, u8 ipproto)
186{ 193{
187 struct net *net = dev_net(skb->dev); 194 struct net *net = dev_net(skb->dev);
188 struct ip_tunnel_net *itn = net_generic(net, ipip_net_id); 195 struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);
@@ -193,11 +200,23 @@ static int ipip_rcv(struct sk_buff *skb)
193 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY, 200 tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, TUNNEL_NO_KEY,
194 iph->saddr, iph->daddr, 0); 201 iph->saddr, iph->daddr, 0);
195 if (tunnel) { 202 if (tunnel) {
203 const struct tnl_ptk_info *tpi;
204
205 if (tunnel->parms.iph.protocol != ipproto &&
206 tunnel->parms.iph.protocol != 0)
207 goto drop;
208
196 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) 209 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
197 goto drop; 210 goto drop;
198 if (iptunnel_pull_header(skb, 0, tpi.proto, false)) 211#if IS_ENABLED(CONFIG_MPLS)
212 if (ipproto == IPPROTO_MPLS)
213 tpi = &mplsip_tpi;
214 else
215#endif
216 tpi = &ipip_tpi;
217 if (iptunnel_pull_header(skb, 0, tpi->proto, false))
199 goto drop; 218 goto drop;
200 return ip_tunnel_rcv(tunnel, skb, &tpi, NULL, log_ecn_error); 219 return ip_tunnel_rcv(tunnel, skb, tpi, NULL, log_ecn_error);
201 } 220 }
202 221
203 return -1; 222 return -1;
@@ -207,24 +226,51 @@ drop:
207 return 0; 226 return 0;
208} 227}
209 228
229static int ipip_rcv(struct sk_buff *skb)
230{
231 return ipip_tunnel_rcv(skb, IPPROTO_IPIP);
232}
233
234#if IS_ENABLED(CONFIG_MPLS)
235static int mplsip_rcv(struct sk_buff *skb)
236{
237 return ipip_tunnel_rcv(skb, IPPROTO_MPLS);
238}
239#endif
240
210/* 241/*
211 * This function assumes it is being called from dev_queue_xmit() 242 * This function assumes it is being called from dev_queue_xmit()
212 * and that skb is filled properly by that function. 243 * and that skb is filled properly by that function.
213 */ 244 */
214static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) 245static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb,
246 struct net_device *dev)
215{ 247{
216 struct ip_tunnel *tunnel = netdev_priv(dev); 248 struct ip_tunnel *tunnel = netdev_priv(dev);
217 const struct iphdr *tiph = &tunnel->parms.iph; 249 const struct iphdr *tiph = &tunnel->parms.iph;
250 u8 ipproto;
251
252 switch (skb->protocol) {
253 case htons(ETH_P_IP):
254 ipproto = IPPROTO_IPIP;
255 break;
256#if IS_ENABLED(CONFIG_MPLS)
257 case htons(ETH_P_MPLS_UC):
258 ipproto = IPPROTO_MPLS;
259 break;
260#endif
261 default:
262 goto tx_error;
263 }
218 264
219 if (unlikely(skb->protocol != htons(ETH_P_IP))) 265 if (tiph->protocol != ipproto && tiph->protocol != 0)
220 goto tx_error; 266 goto tx_error;
221 267
222 if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4)) 268 if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4))
223 goto tx_error; 269 goto tx_error;
224 270
225 skb_set_inner_ipproto(skb, IPPROTO_IPIP); 271 skb_set_inner_ipproto(skb, ipproto);
226 272
227 ip_tunnel_xmit(skb, dev, tiph, tiph->protocol); 273 ip_tunnel_xmit(skb, dev, tiph, ipproto);
228 return NETDEV_TX_OK; 274 return NETDEV_TX_OK;
229 275
230tx_error: 276tx_error:
@@ -234,6 +280,20 @@ tx_error:
234 return NETDEV_TX_OK; 280 return NETDEV_TX_OK;
235} 281}
236 282
283static bool ipip_tunnel_ioctl_verify_protocol(u8 ipproto)
284{
285 switch (ipproto) {
286 case 0:
287 case IPPROTO_IPIP:
288#if IS_ENABLED(CONFIG_MPLS)
289 case IPPROTO_MPLS:
290#endif
291 return true;
292 }
293
294 return false;
295}
296
237static int 297static int
238ipip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 298ipip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
239{ 299{
@@ -244,7 +304,8 @@ ipip_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
244 return -EFAULT; 304 return -EFAULT;
245 305
246 if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) { 306 if (cmd == SIOCADDTUNNEL || cmd == SIOCCHGTUNNEL) {
247 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPIP || 307 if (p.iph.version != 4 ||
308 !ipip_tunnel_ioctl_verify_protocol(p.iph.protocol) ||
248 p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF))) 309 p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)))
249 return -EINVAL; 310 return -EINVAL;
250 } 311 }
@@ -301,10 +362,23 @@ static int ipip_tunnel_init(struct net_device *dev)
301 362
302 tunnel->tun_hlen = 0; 363 tunnel->tun_hlen = 0;
303 tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen; 364 tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen;
304 tunnel->parms.iph.protocol = IPPROTO_IPIP;
305 return ip_tunnel_init(dev); 365 return ip_tunnel_init(dev);
306} 366}
307 367
368static int ipip_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
369{
370 u8 proto;
371
372 if (!data || !data[IFLA_IPTUN_PROTO])
373 return 0;
374
375 proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
376 if (proto != IPPROTO_IPIP && proto != IPPROTO_MPLS && proto != 0)
377 return -EINVAL;
378
379 return 0;
380}
381
308static void ipip_netlink_parms(struct nlattr *data[], 382static void ipip_netlink_parms(struct nlattr *data[],
309 struct ip_tunnel_parm *parms) 383 struct ip_tunnel_parm *parms)
310{ 384{
@@ -335,6 +409,9 @@ static void ipip_netlink_parms(struct nlattr *data[],
335 if (data[IFLA_IPTUN_TOS]) 409 if (data[IFLA_IPTUN_TOS])
336 parms->iph.tos = nla_get_u8(data[IFLA_IPTUN_TOS]); 410 parms->iph.tos = nla_get_u8(data[IFLA_IPTUN_TOS]);
337 411
412 if (data[IFLA_IPTUN_PROTO])
413 parms->iph.protocol = nla_get_u8(data[IFLA_IPTUN_PROTO]);
414
338 if (!data[IFLA_IPTUN_PMTUDISC] || nla_get_u8(data[IFLA_IPTUN_PMTUDISC])) 415 if (!data[IFLA_IPTUN_PMTUDISC] || nla_get_u8(data[IFLA_IPTUN_PMTUDISC]))
339 parms->iph.frag_off = htons(IP_DF); 416 parms->iph.frag_off = htons(IP_DF);
340} 417}
@@ -427,6 +504,8 @@ static size_t ipip_get_size(const struct net_device *dev)
427 nla_total_size(1) + 504 nla_total_size(1) +
428 /* IFLA_IPTUN_TOS */ 505 /* IFLA_IPTUN_TOS */
429 nla_total_size(1) + 506 nla_total_size(1) +
507 /* IFLA_IPTUN_PROTO */
508 nla_total_size(1) +
430 /* IFLA_IPTUN_PMTUDISC */ 509 /* IFLA_IPTUN_PMTUDISC */
431 nla_total_size(1) + 510 nla_total_size(1) +
432 /* IFLA_IPTUN_ENCAP_TYPE */ 511 /* IFLA_IPTUN_ENCAP_TYPE */
@@ -450,6 +529,7 @@ static int ipip_fill_info(struct sk_buff *skb, const struct net_device *dev)
450 nla_put_in_addr(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) || 529 nla_put_in_addr(skb, IFLA_IPTUN_REMOTE, parm->iph.daddr) ||
451 nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) || 530 nla_put_u8(skb, IFLA_IPTUN_TTL, parm->iph.ttl) ||
452 nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) || 531 nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) ||
532 nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->iph.protocol) ||
453 nla_put_u8(skb, IFLA_IPTUN_PMTUDISC, 533 nla_put_u8(skb, IFLA_IPTUN_PMTUDISC,
454 !!(parm->iph.frag_off & htons(IP_DF)))) 534 !!(parm->iph.frag_off & htons(IP_DF))))
455 goto nla_put_failure; 535 goto nla_put_failure;
@@ -476,6 +556,7 @@ static const struct nla_policy ipip_policy[IFLA_IPTUN_MAX + 1] = {
476 [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 }, 556 [IFLA_IPTUN_REMOTE] = { .type = NLA_U32 },
477 [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, 557 [IFLA_IPTUN_TTL] = { .type = NLA_U8 },
478 [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, 558 [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
559 [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
479 [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, 560 [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
480 [IFLA_IPTUN_ENCAP_TYPE] = { .type = NLA_U16 }, 561 [IFLA_IPTUN_ENCAP_TYPE] = { .type = NLA_U16 },
481 [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 }, 562 [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NLA_U16 },
@@ -489,6 +570,7 @@ static struct rtnl_link_ops ipip_link_ops __read_mostly = {
489 .policy = ipip_policy, 570 .policy = ipip_policy,
490 .priv_size = sizeof(struct ip_tunnel), 571 .priv_size = sizeof(struct ip_tunnel),
491 .setup = ipip_tunnel_setup, 572 .setup = ipip_tunnel_setup,
573 .validate = ipip_tunnel_validate,
492 .newlink = ipip_newlink, 574 .newlink = ipip_newlink,
493 .changelink = ipip_changelink, 575 .changelink = ipip_changelink,
494 .dellink = ip_tunnel_dellink, 576 .dellink = ip_tunnel_dellink,
@@ -503,6 +585,14 @@ static struct xfrm_tunnel ipip_handler __read_mostly = {
503 .priority = 1, 585 .priority = 1,
504}; 586};
505 587
588#if IS_ENABLED(CONFIG_MPLS)
589static struct xfrm_tunnel mplsip_handler __read_mostly = {
590 .handler = mplsip_rcv,
591 .err_handler = ipip_err,
592 .priority = 1,
593};
594#endif
595
506static int __net_init ipip_init_net(struct net *net) 596static int __net_init ipip_init_net(struct net *net)
507{ 597{
508 return ip_tunnel_init_net(net, ipip_net_id, &ipip_link_ops, "tunl0"); 598 return ip_tunnel_init_net(net, ipip_net_id, &ipip_link_ops, "tunl0");
@@ -525,7 +615,7 @@ static int __init ipip_init(void)
525{ 615{
526 int err; 616 int err;
527 617
528 pr_info("ipip: IPv4 over IPv4 tunneling driver\n"); 618 pr_info("ipip: IPv4 and MPLS over IPv4 tunneling driver\n");
529 619
530 err = register_pernet_device(&ipip_net_ops); 620 err = register_pernet_device(&ipip_net_ops);
531 if (err < 0) 621 if (err < 0)
@@ -533,8 +623,15 @@ static int __init ipip_init(void)
533 err = xfrm4_tunnel_register(&ipip_handler, AF_INET); 623 err = xfrm4_tunnel_register(&ipip_handler, AF_INET);
534 if (err < 0) { 624 if (err < 0) {
535 pr_info("%s: can't register tunnel\n", __func__); 625 pr_info("%s: can't register tunnel\n", __func__);
536 goto xfrm_tunnel_failed; 626 goto xfrm_tunnel_ipip_failed;
627 }
628#if IS_ENABLED(CONFIG_MPLS)
629 err = xfrm4_tunnel_register(&mplsip_handler, AF_MPLS);
630 if (err < 0) {
631 pr_info("%s: can't register tunnel\n", __func__);
632 goto xfrm_tunnel_mplsip_failed;
537 } 633 }
634#endif
538 err = rtnl_link_register(&ipip_link_ops); 635 err = rtnl_link_register(&ipip_link_ops);
539 if (err < 0) 636 if (err < 0)
540 goto rtnl_link_failed; 637 goto rtnl_link_failed;
@@ -543,8 +640,13 @@ out:
543 return err; 640 return err;
544 641
545rtnl_link_failed: 642rtnl_link_failed:
643#if IS_ENABLED(CONFIG_MPLS)
644 xfrm4_tunnel_deregister(&mplsip_handler, AF_INET);
645xfrm_tunnel_mplsip_failed:
646
647#endif
546 xfrm4_tunnel_deregister(&ipip_handler, AF_INET); 648 xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
547xfrm_tunnel_failed: 649xfrm_tunnel_ipip_failed:
548 unregister_pernet_device(&ipip_net_ops); 650 unregister_pernet_device(&ipip_net_ops);
549 goto out; 651 goto out;
550} 652}
@@ -554,7 +656,10 @@ static void __exit ipip_fini(void)
554 rtnl_link_unregister(&ipip_link_ops); 656 rtnl_link_unregister(&ipip_link_ops);
555 if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET)) 657 if (xfrm4_tunnel_deregister(&ipip_handler, AF_INET))
556 pr_info("%s: can't deregister tunnel\n", __func__); 658 pr_info("%s: can't deregister tunnel\n", __func__);
557 659#if IS_ENABLED(CONFIG_MPLS)
660 if (xfrm4_tunnel_deregister(&mplsip_handler, AF_MPLS))
661 pr_info("%s: can't deregister tunnel\n", __func__);
662#endif
558 unregister_pernet_device(&ipip_net_ops); 663 unregister_pernet_device(&ipip_net_ops);
559} 664}
560 665