aboutsummaryrefslogtreecommitdiffstats
path: root/net/mpls/af_mpls.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mpls/af_mpls.c')
-rw-r--r--net/mpls/af_mpls.c197
1 files changed, 154 insertions, 43 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 1f93a5978f2a..8c5707db53c5 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -15,6 +15,10 @@
15#include <net/ip_fib.h> 15#include <net/ip_fib.h>
16#include <net/netevent.h> 16#include <net/netevent.h>
17#include <net/netns/generic.h> 17#include <net/netns/generic.h>
18#if IS_ENABLED(CONFIG_IPV6)
19#include <net/ipv6.h>
20#include <net/addrconf.h>
21#endif
18#include "internal.h" 22#include "internal.h"
19 23
20#define LABEL_NOT_SPECIFIED (1<<20) 24#define LABEL_NOT_SPECIFIED (1<<20)
@@ -23,11 +27,23 @@
23/* This maximum ha length copied from the definition of struct neighbour */ 27/* This maximum ha length copied from the definition of struct neighbour */
24#define MAX_VIA_ALEN (ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))) 28#define MAX_VIA_ALEN (ALIGN(MAX_ADDR_LEN, sizeof(unsigned long)))
25 29
30enum mpls_payload_type {
31 MPT_UNSPEC, /* IPv4 or IPv6 */
32 MPT_IPV4 = 4,
33 MPT_IPV6 = 6,
34
35 /* Other types not implemented:
36 * - Pseudo-wire with or without control word (RFC4385)
37 * - GAL (RFC5586)
38 */
39};
40
26struct mpls_route { /* next hop label forwarding entry */ 41struct mpls_route { /* next hop label forwarding entry */
27 struct net_device __rcu *rt_dev; 42 struct net_device __rcu *rt_dev;
28 struct rcu_head rt_rcu; 43 struct rcu_head rt_rcu;
29 u32 rt_label[MAX_NEW_LABELS]; 44 u32 rt_label[MAX_NEW_LABELS];
30 u8 rt_protocol; /* routing protocol that set this entry */ 45 u8 rt_protocol; /* routing protocol that set this entry */
46 u8 rt_payload_type;
31 u8 rt_labels; 47 u8 rt_labels;
32 u8 rt_via_alen; 48 u8 rt_via_alen;
33 u8 rt_via_table; 49 u8 rt_via_table;
@@ -58,10 +74,11 @@ static inline struct mpls_dev *mpls_dev_get(const struct net_device *dev)
58 return rcu_dereference_rtnl(dev->mpls_ptr); 74 return rcu_dereference_rtnl(dev->mpls_ptr);
59} 75}
60 76
61static bool mpls_output_possible(const struct net_device *dev) 77bool mpls_output_possible(const struct net_device *dev)
62{ 78{
63 return dev && (dev->flags & IFF_UP) && netif_carrier_ok(dev); 79 return dev && (dev->flags & IFF_UP) && netif_carrier_ok(dev);
64} 80}
81EXPORT_SYMBOL_GPL(mpls_output_possible);
65 82
66static unsigned int mpls_rt_header_size(const struct mpls_route *rt) 83static unsigned int mpls_rt_header_size(const struct mpls_route *rt)
67{ 84{
@@ -69,13 +86,14 @@ static unsigned int mpls_rt_header_size(const struct mpls_route *rt)
69 return rt->rt_labels * sizeof(struct mpls_shim_hdr); 86 return rt->rt_labels * sizeof(struct mpls_shim_hdr);
70} 87}
71 88
72static unsigned int mpls_dev_mtu(const struct net_device *dev) 89unsigned int mpls_dev_mtu(const struct net_device *dev)
73{ 90{
74 /* The amount of data the layer 2 frame can hold */ 91 /* The amount of data the layer 2 frame can hold */
75 return dev->mtu; 92 return dev->mtu;
76} 93}
94EXPORT_SYMBOL_GPL(mpls_dev_mtu);
77 95
78static bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) 96bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
79{ 97{
80 if (skb->len <= mtu) 98 if (skb->len <= mtu)
81 return false; 99 return false;
@@ -85,20 +103,13 @@ static bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
85 103
86 return true; 104 return true;
87} 105}
106EXPORT_SYMBOL_GPL(mpls_pkt_too_big);
88 107
89static bool mpls_egress(struct mpls_route *rt, struct sk_buff *skb, 108static bool mpls_egress(struct mpls_route *rt, struct sk_buff *skb,
90 struct mpls_entry_decoded dec) 109 struct mpls_entry_decoded dec)
91{ 110{
92 /* RFC4385 and RFC5586 encode other packets in mpls such that 111 enum mpls_payload_type payload_type;
93 * they don't conflict with the ip version number, making 112 bool success = false;
94 * decoding by examining the ip version correct in everything
95 * except for the strangest cases.
96 *
97 * The strange cases if we choose to support them will require
98 * manual configuration.
99 */
100 struct iphdr *hdr4;
101 bool success = true;
102 113
103 /* The IPv4 code below accesses through the IPv4 header 114 /* The IPv4 code below accesses through the IPv4 header
104 * checksum, which is 12 bytes into the packet. 115 * checksum, which is 12 bytes into the packet.
@@ -113,23 +124,32 @@ static bool mpls_egress(struct mpls_route *rt, struct sk_buff *skb,
113 if (!pskb_may_pull(skb, 12)) 124 if (!pskb_may_pull(skb, 12))
114 return false; 125 return false;
115 126
116 /* Use ip_hdr to find the ip protocol version */ 127 payload_type = rt->rt_payload_type;
117 hdr4 = ip_hdr(skb); 128 if (payload_type == MPT_UNSPEC)
118 if (hdr4->version == 4) { 129 payload_type = ip_hdr(skb)->version;
130
131 switch (payload_type) {
132 case MPT_IPV4: {
133 struct iphdr *hdr4 = ip_hdr(skb);
119 skb->protocol = htons(ETH_P_IP); 134 skb->protocol = htons(ETH_P_IP);
120 csum_replace2(&hdr4->check, 135 csum_replace2(&hdr4->check,
121 htons(hdr4->ttl << 8), 136 htons(hdr4->ttl << 8),
122 htons(dec.ttl << 8)); 137 htons(dec.ttl << 8));
123 hdr4->ttl = dec.ttl; 138 hdr4->ttl = dec.ttl;
139 success = true;
140 break;
124 } 141 }
125 else if (hdr4->version == 6) { 142 case MPT_IPV6: {
126 struct ipv6hdr *hdr6 = ipv6_hdr(skb); 143 struct ipv6hdr *hdr6 = ipv6_hdr(skb);
127 skb->protocol = htons(ETH_P_IPV6); 144 skb->protocol = htons(ETH_P_IPV6);
128 hdr6->hop_limit = dec.ttl; 145 hdr6->hop_limit = dec.ttl;
146 success = true;
147 break;
148 }
149 case MPT_UNSPEC:
150 break;
129 } 151 }
130 else 152
131 /* version 0 and version 1 are used by pseudo wires */
132 success = false;
133 return success; 153 return success;
134} 154}
135 155
@@ -248,16 +268,17 @@ static const struct nla_policy rtm_mpls_policy[RTA_MAX+1] = {
248}; 268};
249 269
250struct mpls_route_config { 270struct mpls_route_config {
251 u32 rc_protocol; 271 u32 rc_protocol;
252 u32 rc_ifindex; 272 u32 rc_ifindex;
253 u16 rc_via_table; 273 u16 rc_via_table;
254 u16 rc_via_alen; 274 u16 rc_via_alen;
255 u8 rc_via[MAX_VIA_ALEN]; 275 u8 rc_via[MAX_VIA_ALEN];
256 u32 rc_label; 276 u32 rc_label;
257 u32 rc_output_labels; 277 u32 rc_output_labels;
258 u32 rc_output_label[MAX_NEW_LABELS]; 278 u32 rc_output_label[MAX_NEW_LABELS];
259 u32 rc_nlflags; 279 u32 rc_nlflags;
260 struct nl_info rc_nlinfo; 280 enum mpls_payload_type rc_payload_type;
281 struct nl_info rc_nlinfo;
261}; 282};
262 283
263static struct mpls_route *mpls_rt_alloc(size_t alen) 284static struct mpls_route *mpls_rt_alloc(size_t alen)
@@ -286,7 +307,7 @@ static void mpls_notify_route(struct net *net, unsigned index,
286 struct mpls_route *rt = new ? new : old; 307 struct mpls_route *rt = new ? new : old;
287 unsigned nlm_flags = (old && new) ? NLM_F_REPLACE : 0; 308 unsigned nlm_flags = (old && new) ? NLM_F_REPLACE : 0;
288 /* Ignore reserved labels for now */ 309 /* Ignore reserved labels for now */
289 if (rt && (index >= 16)) 310 if (rt && (index >= MPLS_LABEL_FIRST_UNRESERVED))
290 rtmsg_lfib(event, index, rt, nlh, net, portid, nlm_flags); 311 rtmsg_lfib(event, index, rt, nlh, net, portid, nlm_flags);
291} 312}
292 313
@@ -320,13 +341,96 @@ static unsigned find_free_label(struct net *net)
320 341
321 platform_label = rtnl_dereference(net->mpls.platform_label); 342 platform_label = rtnl_dereference(net->mpls.platform_label);
322 platform_labels = net->mpls.platform_labels; 343 platform_labels = net->mpls.platform_labels;
323 for (index = 16; index < platform_labels; index++) { 344 for (index = MPLS_LABEL_FIRST_UNRESERVED; index < platform_labels;
345 index++) {
324 if (!rtnl_dereference(platform_label[index])) 346 if (!rtnl_dereference(platform_label[index]))
325 return index; 347 return index;
326 } 348 }
327 return LABEL_NOT_SPECIFIED; 349 return LABEL_NOT_SPECIFIED;
328} 350}
329 351
352#if IS_ENABLED(CONFIG_INET)
353static struct net_device *inet_fib_lookup_dev(struct net *net, void *addr)
354{
355 struct net_device *dev;
356 struct rtable *rt;
357 struct in_addr daddr;
358
359 memcpy(&daddr, addr, sizeof(struct in_addr));
360 rt = ip_route_output(net, daddr.s_addr, 0, 0, 0);
361 if (IS_ERR(rt))
362 return ERR_CAST(rt);
363
364 dev = rt->dst.dev;
365 dev_hold(dev);
366
367 ip_rt_put(rt);
368
369 return dev;
370}
371#else
372static struct net_device *inet_fib_lookup_dev(struct net *net, void *addr)
373{
374 return ERR_PTR(-EAFNOSUPPORT);
375}
376#endif
377
378#if IS_ENABLED(CONFIG_IPV6)
379static struct net_device *inet6_fib_lookup_dev(struct net *net, void *addr)
380{
381 struct net_device *dev;
382 struct dst_entry *dst;
383 struct flowi6 fl6;
384 int err;
385
386 if (!ipv6_stub)
387 return ERR_PTR(-EAFNOSUPPORT);
388
389 memset(&fl6, 0, sizeof(fl6));
390 memcpy(&fl6.daddr, addr, sizeof(struct in6_addr));
391 err = ipv6_stub->ipv6_dst_lookup(net, NULL, &dst, &fl6);
392 if (err)
393 return ERR_PTR(err);
394
395 dev = dst->dev;
396 dev_hold(dev);
397 dst_release(dst);
398
399 return dev;
400}
401#else
402static struct net_device *inet6_fib_lookup_dev(struct net *net, void *addr)
403{
404 return ERR_PTR(-EAFNOSUPPORT);
405}
406#endif
407
408static struct net_device *find_outdev(struct net *net,
409 struct mpls_route_config *cfg)
410{
411 struct net_device *dev = NULL;
412
413 if (!cfg->rc_ifindex) {
414 switch (cfg->rc_via_table) {
415 case NEIGH_ARP_TABLE:
416 dev = inet_fib_lookup_dev(net, cfg->rc_via);
417 break;
418 case NEIGH_ND_TABLE:
419 dev = inet6_fib_lookup_dev(net, cfg->rc_via);
420 break;
421 case NEIGH_LINK_TABLE:
422 break;
423 }
424 } else {
425 dev = dev_get_by_index(net, cfg->rc_ifindex);
426 }
427
428 if (!dev)
429 return ERR_PTR(-ENODEV);
430
431 return dev;
432}
433
330static int mpls_route_add(struct mpls_route_config *cfg) 434static int mpls_route_add(struct mpls_route_config *cfg)
331{ 435{
332 struct mpls_route __rcu **platform_label; 436 struct mpls_route __rcu **platform_label;
@@ -345,8 +449,8 @@ static int mpls_route_add(struct mpls_route_config *cfg)
345 index = find_free_label(net); 449 index = find_free_label(net);
346 } 450 }
347 451
348 /* The first 16 labels are reserved, and may not be set */ 452 /* Reserved labels may not be set */
349 if (index < 16) 453 if (index < MPLS_LABEL_FIRST_UNRESERVED)
350 goto errout; 454 goto errout;
351 455
352 /* The full 20 bit range may not be supported. */ 456 /* The full 20 bit range may not be supported. */
@@ -357,10 +461,12 @@ static int mpls_route_add(struct mpls_route_config *cfg)
357 if (cfg->rc_output_labels > MAX_NEW_LABELS) 461 if (cfg->rc_output_labels > MAX_NEW_LABELS)
358 goto errout; 462 goto errout;
359 463
360 err = -ENODEV; 464 dev = find_outdev(net, cfg);
361 dev = dev_get_by_index(net, cfg->rc_ifindex); 465 if (IS_ERR(dev)) {
362 if (!dev) 466 err = PTR_ERR(dev);
467 dev = NULL;
363 goto errout; 468 goto errout;
469 }
364 470
365 /* Ensure this is a supported device */ 471 /* Ensure this is a supported device */
366 err = -EINVAL; 472 err = -EINVAL;
@@ -401,6 +507,7 @@ static int mpls_route_add(struct mpls_route_config *cfg)
401 rt->rt_label[i] = cfg->rc_output_label[i]; 507 rt->rt_label[i] = cfg->rc_output_label[i];
402 rt->rt_protocol = cfg->rc_protocol; 508 rt->rt_protocol = cfg->rc_protocol;
403 RCU_INIT_POINTER(rt->rt_dev, dev); 509 RCU_INIT_POINTER(rt->rt_dev, dev);
510 rt->rt_payload_type = cfg->rc_payload_type;
404 rt->rt_via_table = cfg->rc_via_table; 511 rt->rt_via_table = cfg->rc_via_table;
405 memcpy(rt->rt_via, cfg->rc_via, cfg->rc_via_alen); 512 memcpy(rt->rt_via, cfg->rc_via, cfg->rc_via_alen);
406 513
@@ -423,8 +530,8 @@ static int mpls_route_del(struct mpls_route_config *cfg)
423 530
424 index = cfg->rc_label; 531 index = cfg->rc_label;
425 532
426 /* The first 16 labels are reserved, and may not be removed */ 533 /* Reserved labels may not be removed */
427 if (index < 16) 534 if (index < MPLS_LABEL_FIRST_UNRESERVED)
428 goto errout; 535 goto errout;
429 536
430 /* The full 20 bit range may not be supported */ 537 /* The full 20 bit range may not be supported */
@@ -626,6 +733,7 @@ int nla_put_labels(struct sk_buff *skb, int attrtype,
626 733
627 return 0; 734 return 0;
628} 735}
736EXPORT_SYMBOL_GPL(nla_put_labels);
629 737
630int nla_get_labels(const struct nlattr *nla, 738int nla_get_labels(const struct nlattr *nla,
631 u32 max_labels, u32 *labels, u32 label[]) 739 u32 max_labels, u32 *labels, u32 label[])
@@ -671,6 +779,7 @@ int nla_get_labels(const struct nlattr *nla,
671 *labels = nla_labels; 779 *labels = nla_labels;
672 return 0; 780 return 0;
673} 781}
782EXPORT_SYMBOL_GPL(nla_get_labels);
674 783
675static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh, 784static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh,
676 struct mpls_route_config *cfg) 785 struct mpls_route_config *cfg)
@@ -740,8 +849,8 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh,
740 &cfg->rc_label)) 849 &cfg->rc_label))
741 goto errout; 850 goto errout;
742 851
743 /* The first 16 labels are reserved, and may not be set */ 852 /* Reserved labels may not be set */
744 if (cfg->rc_label < 16) 853 if (cfg->rc_label < MPLS_LABEL_FIRST_UNRESERVED)
745 goto errout; 854 goto errout;
746 855
747 break; 856 break;
@@ -866,8 +975,8 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb)
866 ASSERT_RTNL(); 975 ASSERT_RTNL();
867 976
868 index = cb->args[0]; 977 index = cb->args[0];
869 if (index < 16) 978 if (index < MPLS_LABEL_FIRST_UNRESERVED)
870 index = 16; 979 index = MPLS_LABEL_FIRST_UNRESERVED;
871 980
872 platform_label = rtnl_dereference(net->mpls.platform_label); 981 platform_label = rtnl_dereference(net->mpls.platform_label);
873 platform_labels = net->mpls.platform_labels; 982 platform_labels = net->mpls.platform_labels;
@@ -953,6 +1062,7 @@ static int resize_platform_label_table(struct net *net, size_t limit)
953 goto nort0; 1062 goto nort0;
954 RCU_INIT_POINTER(rt0->rt_dev, lo); 1063 RCU_INIT_POINTER(rt0->rt_dev, lo);
955 rt0->rt_protocol = RTPROT_KERNEL; 1064 rt0->rt_protocol = RTPROT_KERNEL;
1065 rt0->rt_payload_type = MPT_IPV4;
956 rt0->rt_via_table = NEIGH_LINK_TABLE; 1066 rt0->rt_via_table = NEIGH_LINK_TABLE;
957 memcpy(rt0->rt_via, lo->dev_addr, lo->addr_len); 1067 memcpy(rt0->rt_via, lo->dev_addr, lo->addr_len);
958 } 1068 }
@@ -963,6 +1073,7 @@ static int resize_platform_label_table(struct net *net, size_t limit)
963 goto nort2; 1073 goto nort2;
964 RCU_INIT_POINTER(rt2->rt_dev, lo); 1074 RCU_INIT_POINTER(rt2->rt_dev, lo);
965 rt2->rt_protocol = RTPROT_KERNEL; 1075 rt2->rt_protocol = RTPROT_KERNEL;
1076 rt2->rt_payload_type = MPT_IPV6;
966 rt2->rt_via_table = NEIGH_LINK_TABLE; 1077 rt2->rt_via_table = NEIGH_LINK_TABLE;
967 memcpy(rt2->rt_via, lo->dev_addr, lo->addr_len); 1078 memcpy(rt2->rt_via, lo->dev_addr, lo->addr_len);
968 } 1079 }