mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge branch 'netlink-add-lwtunnel-encap-sub-message-support-to-rt-route'
Hangbin Liu says:
====================
netlink: add lwtunnel encap sub-message support to rt-route
This series adds YNL sub-message support for lwtunnel encap data in
the rt-route netlink family, and describes the tunnel-specific
attribute sets that were previously opaque binary blobs.
The kernel currently emits encap_type after the encap payload nest,
but YNL sub-message parsing needs the selector (encap_type) first to
dispatch on the correct attribute set. Patch 1 reorders the kernel
output, and patch 2 teaches the YNL C code generator to convert enum
selectors to their string form for sub-message dispatch.
Patches 3-6 extend the rt-route YAML spec.
Tested with ynl selftest and checked with following cmds
# modprobe ila
# modprobe xfrm_interface
# ip addr add 10.1.0.1/24 dev lo
# ip link add geneve1 type geneve id 1 remote 10.1.0.2 ttl 64
# ip link set geneve1 up
# ip route add 10.1.0.0/24 dev lo encap mpls 100 via 10.1.0.254
# ip route add 1.1.1.0/24 encap ip id 1 geneve_opts 1:1:1212121234567891,2:2:1212121234567892,3:3:1212121234567893 dst 10.1.0.2 dev geneve1
# ip route add 2001:db8:3::/64 dev lo encap ila 1:2:3:4 csum-mode no-action ident-type luid hook-type output
# ip route add 2001:db8:4::/64 dev lo encap ip6 id 1 dst 2001:db8::5 src 2001:db8::1 hoplimit 64
# ip route add 2001:db8:5::/64 dev lo encap seg6 mode inline segs 2001:db8::1
# ip route add 2001:db8:6::/65 dev lo encap seg6local action End flavors psp,next-csid lblen 32 nflen 16
# ip route add 2001:db8:7::/65 dev lo encap bpf in ob /tmp/kself/net/lib/xdp_dummy.bpf.o sec xdp
# ip route add 2001:db8:8::/64 dev lo encap rpl segs 2001:db8::1
# ip route add 2001:db8:9::/64 encap ioam6 trace prealloc type 0x800000 ns 0 size 4 dev lo
# ip route add 2001:db8:10::/64 dev lo encap xfrm if_id 100
# ip route show
1.1.1.0/24 encap ip id 1 src 0.0.0.0 dst 10.1.0.2 ttl 0 tos 0
geneve_opts 1:1:1212121234567891,2:2:1212121234567892,3:3:1212121234567893 dev geneve1 scope link
10.1.0.0/24 encap mpls 100 via 10.1.0.254 dev lo
# ip -6 route show
2001:db8:3::/64 encap ila 1:2:3:4 csum-mode no-action ident-type luid hook-type output dev lo metric 1024 pref medium
2001:db8:4::/64 encap ip6 id 1 src 2001:db8::1 dst 2001:db8::5 hoplimit 64 tc 0 dev lo metric 1024 pref medium
2001:db8:5::/64 encap seg6 mode inline segs 2 [ 2001:db8::1 :: ] dev lo metric 1024 pref medium
2001:db8:6::/65 encap seg6local action End flavors psp,next-csid lblen 32 nflen 16 dev lo metric 1024 pref medium
2001:db8:7::/65 encap bpf in xdp_dummy.bpf.o:[xdp] dev lo metric 1024 pref medium
2001:db8:8::/64 encap rpl segs 1 [ 2001:db8::1 ] dev lo metric 1024 pref medium
2001:db8:9::/64 encap ioam6 freq 1/1 mode inline trace prealloc type 0x800000 ns 0 size 4 dev lo metric 1024 pref medium
2001:db8:10::/64 encap xfrm if_id 100 dev lo metric 1024 pref medium
# ./tools/net/ynl/pyynl/cli.py --family rt-route --dump getroute > /tmp/route_dump.json
All the result looks good.
====================
Link: https://patch.msgid.link/20261008-ynl_rt_encap-v4-0-4ed2ccf7f949@kylinos.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
7684c2c796
|
|
@ -99,6 +99,97 @@ definitions:
|
|||
name: ra-withdrawn
|
||||
doc: A Router Advertisement withdrew the route with a zero
|
||||
lifetime.
|
||||
-
|
||||
name: encap-type
|
||||
type: enum
|
||||
name-prefix: lwtunnel-encap-
|
||||
enum-name:
|
||||
entries:
|
||||
- none
|
||||
- mpls
|
||||
- ip
|
||||
- ila
|
||||
- ip6
|
||||
- seg6
|
||||
- bpf
|
||||
- seg6-local
|
||||
- rpl
|
||||
- ioam6
|
||||
- xfrm
|
||||
-
|
||||
name: seg6-local-actions
|
||||
type: enum
|
||||
name-prefix: seg6-local-action-
|
||||
enum-name:
|
||||
entries:
|
||||
- unspec
|
||||
- end
|
||||
- end-x
|
||||
- end-t
|
||||
- end-dx2
|
||||
- end-dx6
|
||||
- end-dx4
|
||||
- end-dt6
|
||||
- end-dt4
|
||||
- end-b6
|
||||
- end-b6-encap
|
||||
- end-bm
|
||||
- end-s
|
||||
- end-as
|
||||
- end-am
|
||||
- end-bpf
|
||||
- end-dt46
|
||||
-
|
||||
name: seg6-local-flv-ops
|
||||
type: enum
|
||||
name-prefix: seg6-local-flv-op-
|
||||
enum-name:
|
||||
entries:
|
||||
-
|
||||
name: unspec
|
||||
-
|
||||
name: psp
|
||||
-
|
||||
name: usp
|
||||
-
|
||||
name: usd
|
||||
-
|
||||
name: next-csid
|
||||
|
||||
sub-messages:
|
||||
-
|
||||
name: encap-data
|
||||
formats:
|
||||
-
|
||||
value: mpls
|
||||
attribute-set: mpls-iptunnel
|
||||
-
|
||||
value: ip
|
||||
attribute-set: lwtunnel-ip
|
||||
-
|
||||
value: ila
|
||||
attribute-set: ila-attrs
|
||||
-
|
||||
value: ip6
|
||||
attribute-set: lwtunnel-ip6
|
||||
-
|
||||
value: seg6
|
||||
attribute-set: seg6-iptunnel
|
||||
-
|
||||
value: bpf
|
||||
attribute-set: lwt-bpf
|
||||
-
|
||||
value: seg6-local
|
||||
attribute-set: seg6-local
|
||||
-
|
||||
value: rpl
|
||||
attribute-set: rpl-iptunnel
|
||||
-
|
||||
value: ioam6
|
||||
attribute-set: ioam6-iptunnel
|
||||
-
|
||||
value: xfrm
|
||||
attribute-set: lwt-xfrm
|
||||
|
||||
attribute-sets:
|
||||
-
|
||||
|
|
@ -174,9 +265,12 @@ attribute-sets:
|
|||
-
|
||||
name: encap-type
|
||||
type: u16
|
||||
enum: encap-type
|
||||
-
|
||||
name: encap
|
||||
type: binary # tunnel specific nest
|
||||
type: sub-message
|
||||
sub-message: encap-data
|
||||
selector: encap-type
|
||||
-
|
||||
name: expires
|
||||
type: u32
|
||||
|
|
@ -277,6 +371,340 @@ attribute-sets:
|
|||
-
|
||||
name: fastopen-no-cookie
|
||||
type: u32
|
||||
-
|
||||
name: mpls-iptunnel
|
||||
name-prefix: mpls-iptunnel-
|
||||
header: linux/mpls_iptunnel.h
|
||||
attributes:
|
||||
-
|
||||
name: dst
|
||||
type: binary
|
||||
-
|
||||
name: ttl
|
||||
type: u8
|
||||
-
|
||||
name: lwtunnel-ip
|
||||
name-prefix: lwtunnel-ip-
|
||||
header: linux/lwtunnel.h
|
||||
attributes:
|
||||
-
|
||||
name: id
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: dst
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: src
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: ttl
|
||||
type: u8
|
||||
-
|
||||
name: tos
|
||||
type: u8
|
||||
-
|
||||
name: flags
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: opts
|
||||
type: nest
|
||||
nested-attributes: lwtunnel-ip-opts
|
||||
-
|
||||
name: ila-attrs
|
||||
name-prefix: ila-attr-
|
||||
header: linux/ila.h
|
||||
attributes:
|
||||
-
|
||||
name: locator
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: identifier
|
||||
type: u64
|
||||
-
|
||||
name: locator-match
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: ifindex
|
||||
type: s32
|
||||
-
|
||||
name: dir
|
||||
type: u32
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: csum-mode
|
||||
type: u8
|
||||
-
|
||||
name: ident-type
|
||||
type: u8
|
||||
-
|
||||
name: hook-type
|
||||
type: u8
|
||||
-
|
||||
name: lwtunnel-ip6
|
||||
name-prefix: lwtunnel-ip6-
|
||||
header: linux/lwtunnel.h
|
||||
attributes:
|
||||
-
|
||||
name: id
|
||||
type: u64
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: dst
|
||||
type: binary
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: src
|
||||
type: binary
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: hoplimit
|
||||
type: u8
|
||||
-
|
||||
name: tc
|
||||
type: u8
|
||||
-
|
||||
name: flags
|
||||
type: u16
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: opts
|
||||
type: nest
|
||||
nested-attributes: lwtunnel-ip-opts
|
||||
-
|
||||
name: seg6-iptunnel
|
||||
name-prefix: seg6-iptunnel-
|
||||
header: linux/seg6_iptunnel.h
|
||||
attributes:
|
||||
-
|
||||
name: srh
|
||||
type: binary
|
||||
-
|
||||
name: src
|
||||
type: binary
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: table
|
||||
type: u32
|
||||
-
|
||||
name: lwt-bpf
|
||||
name-prefix: lwt-bpf-
|
||||
header: linux/lwtunnel.h
|
||||
attributes:
|
||||
-
|
||||
name: in
|
||||
type: nest
|
||||
nested-attributes: lwt-bpf-prog
|
||||
-
|
||||
name: out
|
||||
type: nest
|
||||
nested-attributes: lwt-bpf-prog
|
||||
-
|
||||
name: xmit
|
||||
type: nest
|
||||
nested-attributes: lwt-bpf-prog
|
||||
-
|
||||
name: xmit-headroom
|
||||
type: u32
|
||||
-
|
||||
name: seg6-local
|
||||
name-prefix: seg6-local-
|
||||
header: linux/seg6_local.h
|
||||
attributes:
|
||||
-
|
||||
name: action
|
||||
type: u32
|
||||
enum: seg6-local-actions
|
||||
-
|
||||
name: srh
|
||||
type: binary
|
||||
-
|
||||
name: table
|
||||
type: u32
|
||||
-
|
||||
name: nh4
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
display-hint: ipv4
|
||||
-
|
||||
name: nh6
|
||||
type: binary
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: iif
|
||||
type: u32
|
||||
-
|
||||
name: oif
|
||||
type: u32
|
||||
-
|
||||
name: bpf
|
||||
type: nest
|
||||
nested-attributes: seg6-local-bpf
|
||||
-
|
||||
name: vrftable
|
||||
type: u32
|
||||
-
|
||||
name: counters
|
||||
type: nest
|
||||
nested-attributes: seg6-local-cnt
|
||||
-
|
||||
name: flavors
|
||||
type: nest
|
||||
nested-attributes: seg6-local-flv
|
||||
-
|
||||
name: rpl-iptunnel
|
||||
name-prefix: rpl-iptunnel-
|
||||
header: linux/rpl_iptunnel.h
|
||||
attributes:
|
||||
-
|
||||
name: srh
|
||||
type: binary
|
||||
-
|
||||
name: ioam6-iptunnel
|
||||
name-prefix: ioam6-iptunnel-
|
||||
header: linux/ioam6_iptunnel.h
|
||||
attributes:
|
||||
-
|
||||
name: mode
|
||||
type: u8
|
||||
-
|
||||
name: dst
|
||||
type: binary
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: trace
|
||||
type: binary
|
||||
-
|
||||
name: freq-k
|
||||
type: u32
|
||||
-
|
||||
name: freq-n
|
||||
type: u32
|
||||
-
|
||||
name: src
|
||||
type: binary
|
||||
display-hint: ipv6
|
||||
-
|
||||
name: lwt-xfrm
|
||||
name-prefix: lwt-xfrm-
|
||||
header: linux/lwtunnel.h
|
||||
attributes:
|
||||
-
|
||||
name: if-id
|
||||
type: u32
|
||||
-
|
||||
name: link
|
||||
type: u32
|
||||
-
|
||||
name: lwtunnel-ip-opts
|
||||
name-prefix: lwtunnel-ip-opts-
|
||||
attributes:
|
||||
-
|
||||
name: geneve
|
||||
type: binary
|
||||
-
|
||||
name: vxlan
|
||||
type: nest
|
||||
nested-attributes: lwtunnel-ip-opt-vxlan
|
||||
-
|
||||
name: erspan
|
||||
type: nest
|
||||
nested-attributes: lwtunnel-ip-opt-erspan
|
||||
-
|
||||
name: lwtunnel-ip-opt-vxlan
|
||||
name-prefix: lwtunnel-ip-opt-vxlan-
|
||||
attributes:
|
||||
-
|
||||
name: gbp
|
||||
type: u32
|
||||
-
|
||||
name: lwtunnel-ip-opt-erspan
|
||||
name-prefix: lwtunnel-ip-opt-erspan-
|
||||
attributes:
|
||||
-
|
||||
name: ver
|
||||
type: u8
|
||||
-
|
||||
name: index
|
||||
type: u32
|
||||
byte-order: big-endian
|
||||
-
|
||||
name: dir
|
||||
type: u8
|
||||
-
|
||||
name: hwid
|
||||
type: u8
|
||||
-
|
||||
name: lwt-bpf-prog
|
||||
name-prefix: lwt-bpf-prog-
|
||||
attributes:
|
||||
-
|
||||
name: fd
|
||||
type: u32
|
||||
-
|
||||
name: name
|
||||
type: string
|
||||
checks:
|
||||
max-len: 256
|
||||
-
|
||||
name: seg6-local-bpf
|
||||
name-prefix: seg6-local-bpf-
|
||||
attr-max-name: seg6-local-bpf-prog-max
|
||||
attributes:
|
||||
-
|
||||
name: prog
|
||||
type: u32
|
||||
-
|
||||
name: prog-name
|
||||
type: string
|
||||
checks:
|
||||
max-len: 256
|
||||
-
|
||||
name: seg6-local-cnt
|
||||
name-prefix: seg6-local-cnt-
|
||||
attributes:
|
||||
-
|
||||
name: pad
|
||||
type: pad
|
||||
-
|
||||
name: packets
|
||||
type: u64
|
||||
-
|
||||
name: bytes
|
||||
type: u64
|
||||
-
|
||||
name: errors
|
||||
type: u64
|
||||
-
|
||||
name: seg6-local-flv
|
||||
name-prefix: seg6-local-flv-
|
||||
attributes:
|
||||
-
|
||||
name: operation
|
||||
type: u32
|
||||
enum: seg6-local-flv-ops
|
||||
enum-as-flags: true
|
||||
-
|
||||
name: lcblock-bits
|
||||
type: u8
|
||||
-
|
||||
name: lcnode-fn-bits
|
||||
type: u8
|
||||
|
||||
operations:
|
||||
enum-model: directional
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
|
|||
{
|
||||
const struct lwtunnel_encap_ops *ops;
|
||||
struct nlattr *nest;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!lwtstate)
|
||||
return 0;
|
||||
|
|
@ -240,30 +240,31 @@ int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
|
|||
lwtstate->type > LWTUNNEL_ENCAP_MAX)
|
||||
return 0;
|
||||
|
||||
nest = nla_nest_start_noflag(skb, encap_attr);
|
||||
if (!nest)
|
||||
return -EMSGSIZE;
|
||||
|
||||
ret = -EOPNOTSUPP;
|
||||
rcu_read_lock();
|
||||
ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
|
||||
if (likely(ops && ops->fill_encap))
|
||||
ret = ops->fill_encap(skb, lwtstate);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (ret)
|
||||
goto nla_put_failure;
|
||||
nla_nest_end(skb, nest);
|
||||
ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
|
||||
if (unlikely(!ops || !ops->fill_encap))
|
||||
goto unlock_out;
|
||||
|
||||
ret = nla_put_u16(skb, encap_type_attr, lwtstate->type);
|
||||
if (ret)
|
||||
goto nla_put_failure;
|
||||
goto unlock_out;
|
||||
|
||||
return 0;
|
||||
nest = nla_nest_start_noflag(skb, encap_attr);
|
||||
if (!nest) {
|
||||
ret = -EMSGSIZE;
|
||||
goto unlock_out;
|
||||
}
|
||||
|
||||
nla_put_failure:
|
||||
nla_nest_cancel(skb, nest);
|
||||
ret = ops->fill_encap(skb, lwtstate);
|
||||
if (ret)
|
||||
nla_nest_cancel(skb, nest);
|
||||
else
|
||||
nla_nest_end(skb, nest);
|
||||
|
||||
return (ret == -EOPNOTSUPP ? 0 : ret);
|
||||
unlock_out:
|
||||
rcu_read_unlock();
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lwtunnel_fill_encap);
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,14 @@ CFLAGS_rt-link:=$(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h) \
|
|||
$(call get_hdr_inc,_LINUX_IF_LINK_H,if_link.h)
|
||||
CFLAGS_rt-neigh:=$(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h) \
|
||||
$(call get_hdr_inc,__LINUX_NEIGHBOUR_H,neighbour.h)
|
||||
CFLAGS_rt-route:=$(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h)
|
||||
CFLAGS_rt-route:=$(call get_hdr_inc,_LINUX_ILA_H,ila.h) \
|
||||
$(call get_hdr_inc,_LINUX_IOAM6_IPTUNNEL_H,ioam6_iptunnel.h) \
|
||||
$(call get_hdr_inc,_LINUX_MPLS_IPTUNNEL_H,mpls_iptunnel.h) \
|
||||
$(call get_hdr_inc,_LINUX_RPL_IPTUNNEL_H,rpl_iptunnel.h) \
|
||||
$(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h) \
|
||||
$(call get_hdr_inc,_LINUX_SEG6_IPTUNNEL_H,seg6_iptunnel.h) \
|
||||
$(call get_hdr_inc,_LINUX_SEG6_LOCAL_H,seg6_local.h) \
|
||||
$(call get_hdr_inc,_LWTUNNEL_H_,lwtunnel.h)
|
||||
CFLAGS_rt-rule:=$(call get_hdr_inc,__LINUX_FIB_RULES_H,fib_rules.h)
|
||||
CFLAGS_tc:= $(call get_hdr_inc,__LINUX_RTNETLINK_H,rtnetlink.h) \
|
||||
$(call get_hdr_inc,__LINUX_PKT_SCHED_H,pkt_sched.h) \
|
||||
|
|
|
|||
|
|
@ -951,13 +951,31 @@ class TypeSubMessage(TypeNest):
|
|||
sel_var = f"_sel_{sel}"
|
||||
else:
|
||||
sel_var = f"{var}->{sel}"
|
||||
get_lines = [f'if (!{sel_var})',
|
||||
f'return ynl_submsg_failed(yarg, "{self.name}", "{selector}");',
|
||||
f"if ({self.nested_render_name}_parse(&parg, {sel_var}, attr))",
|
||||
"return YNL_PARSE_CB_ERROR;"]
|
||||
|
||||
local_vars = None
|
||||
|
||||
if self.selector.is_enum_val() and not self.selector.is_external():
|
||||
enum = self.family.consts[self.selector.get_enum_name()]
|
||||
pres_var = f"{var}->_present.{sel}"
|
||||
parse_sel = f"{sel}_str"
|
||||
local_vars = [f'const char *{parse_sel};']
|
||||
|
||||
get_lines = [
|
||||
f'if (!{pres_var})',
|
||||
f'return ynl_submsg_failed(yarg, "{self.name}", "{selector}");',
|
||||
f'{parse_sel} = {enum.render_name}_str({sel_var});',
|
||||
f'if (!{parse_sel})',
|
||||
f'return ynl_submsg_failed(yarg, "{self.name}", "enum-lookup-failed");']
|
||||
else:
|
||||
parse_sel = sel_var
|
||||
get_lines = [f'if (!{parse_sel})',
|
||||
f'return ynl_submsg_failed(yarg, "{self.name}", "{selector}");']
|
||||
|
||||
get_lines += [f"if ({self.nested_render_name}_parse(&parg, {parse_sel}, attr))",
|
||||
"return YNL_PARSE_CB_ERROR;"]
|
||||
init_lines = [f"parg.rsp_policy = &{self.nested_render_name}_nest;",
|
||||
f"parg.data = &{var}->{self.c_name};"]
|
||||
return get_lines, init_lines, None
|
||||
return get_lines, init_lines, local_vars
|
||||
|
||||
|
||||
class Selector:
|
||||
|
|
@ -979,6 +997,12 @@ class Selector:
|
|||
def is_external(self):
|
||||
return self._external
|
||||
|
||||
def is_enum_val(self):
|
||||
return self.get_enum_name() is not None
|
||||
|
||||
def get_enum_name(self):
|
||||
return self.attr and self.attr.attr.get("enum")
|
||||
|
||||
|
||||
class Struct:
|
||||
def __init__(self, family, space_name, type_list=None, fixed_header=None,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user