|
9 | 9 | #include <linux/rtnetlink.h>
|
10 | 10 | #include <linux/slab.h>
|
11 | 11 | #include <net/ipv6_stubs.h>
|
| 12 | +#include <net/lwtunnel.h> |
12 | 13 | #include <net/nexthop.h>
|
13 | 14 | #include <net/route.h>
|
14 | 15 | #include <net/sock.h>
|
@@ -182,6 +183,11 @@ static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh,
|
182 | 183 | break;
|
183 | 184 | }
|
184 | 185 |
|
| 186 | + if (nhi->fib_nhc.nhc_lwtstate && |
| 187 | + lwtunnel_fill_encap(skb, nhi->fib_nhc.nhc_lwtstate, |
| 188 | + NHA_ENCAP, NHA_ENCAP_TYPE) < 0) |
| 189 | + goto nla_put_failure; |
| 190 | + |
185 | 191 | out:
|
186 | 192 | nlmsg_end(skb, nlh);
|
187 | 193 | return 0;
|
@@ -213,6 +219,11 @@ static size_t nh_nlmsg_size(struct nexthop *nh)
|
213 | 219 | break;
|
214 | 220 | }
|
215 | 221 |
|
| 222 | + if (nhi->fib_nhc.nhc_lwtstate) { |
| 223 | + sz += lwtunnel_get_encap_size(nhi->fib_nhc.nhc_lwtstate); |
| 224 | + sz += nla_total_size(2); /* NHA_ENCAP_TYPE */ |
| 225 | + } |
| 226 | + |
216 | 227 | return sz;
|
217 | 228 | }
|
218 | 229 |
|
@@ -370,6 +381,8 @@ static int nh_create_ipv4(struct net *net, struct nexthop *nh,
|
370 | 381 | .fc_gw4 = cfg->gw.ipv4,
|
371 | 382 | .fc_gw_family = cfg->gw.ipv4 ? AF_INET : 0,
|
372 | 383 | .fc_flags = cfg->nh_flags,
|
| 384 | + .fc_encap = cfg->nh_encap, |
| 385 | + .fc_encap_type = cfg->nh_encap_type, |
373 | 386 | };
|
374 | 387 | u32 tb_id = l3mdev_fib_table(cfg->dev);
|
375 | 388 | int err = -EINVAL;
|
@@ -402,6 +415,8 @@ static int nh_create_ipv6(struct net *net, struct nexthop *nh,
|
402 | 415 | .fc_ifindex = cfg->nh_ifindex,
|
403 | 416 | .fc_gateway = cfg->gw.ipv6,
|
404 | 417 | .fc_flags = cfg->nh_flags,
|
| 418 | + .fc_encap = cfg->nh_encap, |
| 419 | + .fc_encap_type = cfg->nh_encap_type, |
405 | 420 | };
|
406 | 421 | int err = -EINVAL;
|
407 | 422 |
|
@@ -561,7 +576,8 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
|
561 | 576 | cfg->nh_id = nla_get_u32(tb[NHA_ID]);
|
562 | 577 |
|
563 | 578 | if (tb[NHA_BLACKHOLE]) {
|
564 |
| - if (tb[NHA_GATEWAY] || tb[NHA_OIF]) { |
| 579 | + if (tb[NHA_GATEWAY] || tb[NHA_OIF] || |
| 580 | + tb[NHA_ENCAP] || tb[NHA_ENCAP_TYPE]) { |
565 | 581 | NL_SET_ERR_MSG(extack, "Blackhole attribute can not be used with gateway or oif");
|
566 | 582 | goto out;
|
567 | 583 | }
|
@@ -626,6 +642,25 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb,
|
626 | 642 | }
|
627 | 643 | }
|
628 | 644 |
|
| 645 | + if (tb[NHA_ENCAP]) { |
| 646 | + cfg->nh_encap = tb[NHA_ENCAP]; |
| 647 | + |
| 648 | + if (!tb[NHA_ENCAP_TYPE]) { |
| 649 | + NL_SET_ERR_MSG(extack, "LWT encapsulation type is missing"); |
| 650 | + goto out; |
| 651 | + } |
| 652 | + |
| 653 | + cfg->nh_encap_type = nla_get_u16(tb[NHA_ENCAP_TYPE]); |
| 654 | + err = lwtunnel_valid_encap_type(cfg->nh_encap_type, extack); |
| 655 | + if (err < 0) |
| 656 | + goto out; |
| 657 | + |
| 658 | + } else if (tb[NHA_ENCAP_TYPE]) { |
| 659 | + NL_SET_ERR_MSG(extack, "LWT encapsulation attribute is missing"); |
| 660 | + goto out; |
| 661 | + } |
| 662 | + |
| 663 | + |
629 | 664 | err = 0;
|
630 | 665 | out:
|
631 | 666 | return err;
|
|
0 commit comments