aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2013-05-27 19:48:16 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-31 20:19:05 -0400
commit32b8a8e59c9c8fa56051d6e9ab2924e469ac4d92 (patch)
tree51ee4bd6009be21d7aab90212f34e1f4f9e46f7f /net/ipv6
parentbf3d6a8f791b2a81279b9ce3201b4970f6fbe51a (diff)
sit: add IPv4 over IPv4 support
This patch adds the support of IPv4 over Ipv4 for the module sit. The gain of this feature is to be able to have 4in4 and 6in4 over the same interface instead of having one interface for 6in4 and another for 4in4 even if encapsulation addresses are the same. To avoid conflicting with ipip module, sit IPv4 over IPv4 protocol is registered with a smaller priority. Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/sit.c119
1 files changed, 116 insertions, 3 deletions
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 335363478bbf..6b9c1f128eaf 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -577,6 +577,10 @@ static int ipip6_rcv(struct sk_buff *skb)
577 if (tunnel != NULL) { 577 if (tunnel != NULL) {
578 struct pcpu_tstats *tstats; 578 struct pcpu_tstats *tstats;
579 579
580 if (tunnel->parms.iph.protocol != IPPROTO_IPV6 &&
581 tunnel->parms.iph.protocol != 0)
582 goto out;
583
580 secpath_reset(skb); 584 secpath_reset(skb);
581 skb->mac_header = skb->network_header; 585 skb->mac_header = skb->network_header;
582 skb_reset_network_header(skb); 586 skb_reset_network_header(skb);
@@ -629,6 +633,35 @@ out:
629 return 0; 633 return 0;
630} 634}
631 635
636static const struct tnl_ptk_info tpi = {
637 /* no tunnel info required for ipip. */
638 .proto = htons(ETH_P_IP),
639};
640
641static int ipip_rcv(struct sk_buff *skb)
642{
643 const struct iphdr *iph = ip_hdr(skb);
644 struct ip_tunnel *tunnel;
645
646 tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
647 iph->saddr, iph->daddr);
648 if (tunnel != NULL) {
649 if (tunnel->parms.iph.protocol != IPPROTO_IPIP &&
650 tunnel->parms.iph.protocol != 0)
651 goto drop;
652
653 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
654 goto drop;
655 return ip_tunnel_rcv(tunnel, skb, &tpi, log_ecn_error);
656 }
657
658 return 1;
659
660drop:
661 kfree_skb(skb);
662 return 0;
663}
664
632/* 665/*
633 * If the IPv6 address comes from 6rd / 6to4 (RFC 3056) addr space this function 666 * If the IPv6 address comes from 6rd / 6to4 (RFC 3056) addr space this function
634 * stores the embedded IPv4 address in v4dst and returns true. 667 * stores the embedded IPv4 address in v4dst and returns true.
@@ -877,6 +910,43 @@ tx_error:
877 return NETDEV_TX_OK; 910 return NETDEV_TX_OK;
878} 911}
879 912
913static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
914{
915 struct ip_tunnel *tunnel = netdev_priv(dev);
916 const struct iphdr *tiph = &tunnel->parms.iph;
917
918 if (likely(!skb->encapsulation)) {
919 skb_reset_inner_headers(skb);
920 skb->encapsulation = 1;
921 }
922
923 ip_tunnel_xmit(skb, dev, tiph, IPPROTO_IPIP);
924 return NETDEV_TX_OK;
925}
926
927static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
928 struct net_device *dev)
929{
930 switch (skb->protocol) {
931 case htons(ETH_P_IP):
932 ipip_tunnel_xmit(skb, dev);
933 break;
934 case htons(ETH_P_IPV6):
935 ipip6_tunnel_xmit(skb, dev);
936 break;
937 default:
938 goto tx_err;
939 }
940
941 return NETDEV_TX_OK;
942
943tx_err:
944 dev->stats.tx_errors++;
945 dev_kfree_skb(skb);
946 return NETDEV_TX_OK;
947
948}
949
880static void ipip6_tunnel_bind_dev(struct net_device *dev) 950static void ipip6_tunnel_bind_dev(struct net_device *dev)
881{ 951{
882 struct net_device *tdev = NULL; 952 struct net_device *tdev = NULL;
@@ -1027,7 +1097,11 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1027 goto done; 1097 goto done;
1028 1098
1029 err = -EINVAL; 1099 err = -EINVAL;
1030 if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPV6 || 1100 if (p.iph.protocol != IPPROTO_IPV6 &&
1101 p.iph.protocol != IPPROTO_IPIP &&
1102 p.iph.protocol != 0)
1103 goto done;
1104 if (p.iph.version != 4 ||
1031 p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF))) 1105 p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)))
1032 goto done; 1106 goto done;
1033 if (p.iph.ttl) 1107 if (p.iph.ttl)
@@ -1164,7 +1238,7 @@ static int ipip6_tunnel_change_mtu(struct net_device *dev, int new_mtu)
1164 1238
1165static const struct net_device_ops ipip6_netdev_ops = { 1239static const struct net_device_ops ipip6_netdev_ops = {
1166 .ndo_uninit = ipip6_tunnel_uninit, 1240 .ndo_uninit = ipip6_tunnel_uninit,
1167 .ndo_start_xmit = ipip6_tunnel_xmit, 1241 .ndo_start_xmit = sit_tunnel_xmit,
1168 .ndo_do_ioctl = ipip6_tunnel_ioctl, 1242 .ndo_do_ioctl = ipip6_tunnel_ioctl,
1169 .ndo_change_mtu = ipip6_tunnel_change_mtu, 1243 .ndo_change_mtu = ipip6_tunnel_change_mtu,
1170 .ndo_get_stats64 = ip_tunnel_get_stats64, 1244 .ndo_get_stats64 = ip_tunnel_get_stats64,
@@ -1232,6 +1306,22 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev)
1232 return 0; 1306 return 0;
1233} 1307}
1234 1308
1309static int ipip6_validate(struct nlattr *tb[], struct nlattr *data[])
1310{
1311 u8 proto;
1312
1313 if (!data)
1314 return 0;
1315
1316 proto = nla_get_u8(data[IFLA_IPTUN_PROTO]);
1317 if (proto != IPPROTO_IPV6 &&
1318 proto != IPPROTO_IPIP &&
1319 proto != 0)
1320 return -EINVAL;
1321
1322 return 0;
1323}
1324
1235static void ipip6_netlink_parms(struct nlattr *data[], 1325static void ipip6_netlink_parms(struct nlattr *data[],
1236 struct ip_tunnel_parm *parms) 1326 struct ip_tunnel_parm *parms)
1237{ 1327{
@@ -1268,6 +1358,10 @@ static void ipip6_netlink_parms(struct nlattr *data[],
1268 1358
1269 if (data[IFLA_IPTUN_FLAGS]) 1359 if (data[IFLA_IPTUN_FLAGS])
1270 parms->i_flags = nla_get_be16(data[IFLA_IPTUN_FLAGS]); 1360 parms->i_flags = nla_get_be16(data[IFLA_IPTUN_FLAGS]);
1361
1362 if (data[IFLA_IPTUN_PROTO])
1363 parms->iph.protocol = nla_get_u8(data[IFLA_IPTUN_PROTO]);
1364
1271} 1365}
1272 1366
1273#ifdef CONFIG_IPV6_SIT_6RD 1367#ifdef CONFIG_IPV6_SIT_6RD
@@ -1391,6 +1485,8 @@ static size_t ipip6_get_size(const struct net_device *dev)
1391 nla_total_size(1) + 1485 nla_total_size(1) +
1392 /* IFLA_IPTUN_FLAGS */ 1486 /* IFLA_IPTUN_FLAGS */
1393 nla_total_size(2) + 1487 nla_total_size(2) +
1488 /* IFLA_IPTUN_PROTO */
1489 nla_total_size(1) +
1394#ifdef CONFIG_IPV6_SIT_6RD 1490#ifdef CONFIG_IPV6_SIT_6RD
1395 /* IFLA_IPTUN_6RD_PREFIX */ 1491 /* IFLA_IPTUN_6RD_PREFIX */
1396 nla_total_size(sizeof(struct in6_addr)) + 1492 nla_total_size(sizeof(struct in6_addr)) +
@@ -1416,6 +1512,7 @@ static int ipip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
1416 nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) || 1512 nla_put_u8(skb, IFLA_IPTUN_TOS, parm->iph.tos) ||
1417 nla_put_u8(skb, IFLA_IPTUN_PMTUDISC, 1513 nla_put_u8(skb, IFLA_IPTUN_PMTUDISC,
1418 !!(parm->iph.frag_off & htons(IP_DF))) || 1514 !!(parm->iph.frag_off & htons(IP_DF))) ||
1515 nla_put_u8(skb, IFLA_IPTUN_PROTO, parm->iph.protocol) ||
1419 nla_put_be16(skb, IFLA_IPTUN_FLAGS, parm->i_flags)) 1516 nla_put_be16(skb, IFLA_IPTUN_FLAGS, parm->i_flags))
1420 goto nla_put_failure; 1517 goto nla_put_failure;
1421 1518
@@ -1445,6 +1542,7 @@ static const struct nla_policy ipip6_policy[IFLA_IPTUN_MAX + 1] = {
1445 [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, 1542 [IFLA_IPTUN_TOS] = { .type = NLA_U8 },
1446 [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, 1543 [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 },
1447 [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 }, 1544 [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 },
1545 [IFLA_IPTUN_PROTO] = { .type = NLA_U8 },
1448#ifdef CONFIG_IPV6_SIT_6RD 1546#ifdef CONFIG_IPV6_SIT_6RD
1449 [IFLA_IPTUN_6RD_PREFIX] = { .len = sizeof(struct in6_addr) }, 1547 [IFLA_IPTUN_6RD_PREFIX] = { .len = sizeof(struct in6_addr) },
1450 [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 }, 1548 [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 },
@@ -1459,6 +1557,7 @@ static struct rtnl_link_ops sit_link_ops __read_mostly = {
1459 .policy = ipip6_policy, 1557 .policy = ipip6_policy,
1460 .priv_size = sizeof(struct ip_tunnel), 1558 .priv_size = sizeof(struct ip_tunnel),
1461 .setup = ipip6_tunnel_setup, 1559 .setup = ipip6_tunnel_setup,
1560 .validate = ipip6_validate,
1462 .newlink = ipip6_newlink, 1561 .newlink = ipip6_newlink,
1463 .changelink = ipip6_changelink, 1562 .changelink = ipip6_changelink,
1464 .get_size = ipip6_get_size, 1563 .get_size = ipip6_get_size,
@@ -1471,6 +1570,12 @@ static struct xfrm_tunnel sit_handler __read_mostly = {
1471 .priority = 1, 1570 .priority = 1,
1472}; 1571};
1473 1572
1573static struct xfrm_tunnel ipip_handler __read_mostly = {
1574 .handler = ipip_rcv,
1575 .err_handler = ipip6_err,
1576 .priority = 2,
1577};
1578
1474static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head) 1579static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_head *head)
1475{ 1580{
1476 int prio; 1581 int prio;
@@ -1553,6 +1658,7 @@ static void __exit sit_cleanup(void)
1553{ 1658{
1554 rtnl_link_unregister(&sit_link_ops); 1659 rtnl_link_unregister(&sit_link_ops);
1555 xfrm4_tunnel_deregister(&sit_handler, AF_INET6); 1660 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
1661 xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
1556 1662
1557 unregister_pernet_device(&sit_net_ops); 1663 unregister_pernet_device(&sit_net_ops);
1558 rcu_barrier(); /* Wait for completion of call_rcu()'s */ 1664 rcu_barrier(); /* Wait for completion of call_rcu()'s */
@@ -1569,9 +1675,14 @@ static int __init sit_init(void)
1569 return err; 1675 return err;
1570 err = xfrm4_tunnel_register(&sit_handler, AF_INET6); 1676 err = xfrm4_tunnel_register(&sit_handler, AF_INET6);
1571 if (err < 0) { 1677 if (err < 0) {
1572 pr_info("%s: can't add protocol\n", __func__); 1678 pr_info("%s: can't register ip6ip4\n", __func__);
1573 goto xfrm_tunnel_failed; 1679 goto xfrm_tunnel_failed;
1574 } 1680 }
1681 err = xfrm4_tunnel_register(&ipip_handler, AF_INET);
1682 if (err < 0) {
1683 pr_info("%s: can't register ip4ip4\n", __func__);
1684 goto xfrm_tunnel4_failed;
1685 }
1575 err = rtnl_link_register(&sit_link_ops); 1686 err = rtnl_link_register(&sit_link_ops);
1576 if (err < 0) 1687 if (err < 0)
1577 goto rtnl_link_failed; 1688 goto rtnl_link_failed;
@@ -1580,6 +1691,8 @@ out:
1580 return err; 1691 return err;
1581 1692
1582rtnl_link_failed: 1693rtnl_link_failed:
1694 xfrm4_tunnel_deregister(&ipip_handler, AF_INET);
1695xfrm_tunnel4_failed:
1583 xfrm4_tunnel_deregister(&sit_handler, AF_INET6); 1696 xfrm4_tunnel_deregister(&sit_handler, AF_INET6);
1584xfrm_tunnel_failed: 1697xfrm_tunnel_failed:
1585 unregister_pernet_device(&sit_net_ops); 1698 unregister_pernet_device(&sit_net_ops);