* Re: [PATCH iproute2] ip: add support for seg6local End.BPF action
2018-07-16 14:47 [PATCH iproute2] ip: add support for seg6local End.BPF action Mathieu Xhonneux
@ 2018-07-16 12:51 ` Mathieu Xhonneux
2018-07-16 14:48 ` Stephen Hemminger
1 sibling, 0 replies; 3+ messages in thread
From: Mathieu Xhonneux @ 2018-07-16 12:51 UTC (permalink / raw)
To: netdev; +Cc: stephen, David Ahern, David Lebrun
This patch corresponds to a new feature that is now available in the
net tree. I hence assumed that this patch had to be sent to iproute2
and not iproute2-next, please tell me if this is not OK, I'll then
send a v2 towards iproute2-next.
Thanks.
2018-07-16 14:47 GMT+00:00 Mathieu Xhonneux <m.xhonneux@gmail.com>:
> This patch adds support for the End.BPF action of the seg6local
> lightweight tunnel. Functions from the BPF lightweight tunnel are
> re-used in this patch. Example:
>
> $ ip -6 route add fc00::18 encap seg6local action End.BPF obj my_bpf.o
> sec my_func dev eth0
>
> $ ip -6 route show fc00::18
> fc00::18 encap seg6local action End.BPF my_bpf.o:[my_func] dev eth0
> metric 1024 pref medium
>
> Signed-off-by: Mathieu Xhonneux <m.xhonneux@gmail.com>
> ---
> ip/iproute_lwtunnel.c | 122 +++++++++++++++++++++++++++++---------------------
> lib/bpf.c | 5 +++
> 2 files changed, 77 insertions(+), 50 deletions(-)
>
> diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
> index 46a212c8..71c3d8a4 100644
> --- a/ip/iproute_lwtunnel.c
> +++ b/ip/iproute_lwtunnel.c
> @@ -177,6 +177,7 @@ static const char *seg6_action_names[SEG6_LOCAL_ACTION_MAX + 1] = {
> [SEG6_LOCAL_ACTION_END_S] = "End.S",
> [SEG6_LOCAL_ACTION_END_AS] = "End.AS",
> [SEG6_LOCAL_ACTION_END_AM] = "End.AM",
> + [SEG6_LOCAL_ACTION_END_BPF] = "End.BPF",
> };
>
> static const char *format_action_type(int action)
> @@ -250,6 +251,15 @@ static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
> print_string(PRINT_ANY, "oif",
> "oif %s ", ll_index_to_name(oif));
> }
> +
> + if (tb[SEG6_LOCAL_BPF]) {
> + struct rtattr *tb_bpf[LWT_BPF_PROG_MAX+1];
> +
> + parse_rtattr_nested(tb_bpf, LWT_BPF_PROG_MAX, tb[SEG6_LOCAL_BPF]);
> +
> + if (tb_bpf[LWT_BPF_PROG_NAME])
> + fprintf(fp, "%s ", rta_getattr_str(tb_bpf[LWT_BPF_PROG_NAME]));
> + }
> }
>
> static void print_encap_mpls(FILE *fp, struct rtattr *encap)
> @@ -546,11 +556,60 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
> return 0;
> }
>
> +struct lwt_x {
> + struct rtattr *rta;
> + size_t len;
> +};
> +
> +static void bpf_lwt_cb(void *lwt_ptr, int fd, const char *annotation)
> +{
> + struct lwt_x *x = lwt_ptr;
> +
> + rta_addattr32(x->rta, x->len, LWT_BPF_PROG_FD, fd);
> + rta_addattr_l(x->rta, x->len, LWT_BPF_PROG_NAME, annotation,
> + strlen(annotation) + 1);
> +}
> +
> +static const struct bpf_cfg_ops bpf_cb_ops = {
> + .ebpf_cb = bpf_lwt_cb,
> +};
> +
> +static int lwt_parse_bpf(struct rtattr *rta, size_t len,
> + int *argcp, char ***argvp,
> + int attr, const enum bpf_prog_type bpf_type)
> +{
> + struct bpf_cfg_in cfg = {
> + .type = bpf_type,
> + .argc = *argcp,
> + .argv = *argvp,
> + };
> + struct lwt_x x = {
> + .rta = rta,
> + .len = len,
> + };
> + struct rtattr *nest;
> + int err;
> +
> + nest = rta_nest(rta, len, attr);
> + err = bpf_parse_and_load_common(&cfg, &bpf_cb_ops, &x);
> + if (err < 0) {
> + fprintf(stderr, "Failed to parse eBPF program: %s\n",
> + strerror(-err));
> + return -1;
> + }
> + rta_nest_end(rta, nest);
> +
> + *argcp = cfg.argc;
> + *argvp = cfg.argv;
> +
> + return 0;
> +}
> +
> static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
> char ***argvp)
> {
> int segs_ok = 0, hmac_ok = 0, table_ok = 0, nh4_ok = 0, nh6_ok = 0;
> - int iif_ok = 0, oif_ok = 0, action_ok = 0, srh_ok = 0;
> + int iif_ok = 0, oif_ok = 0, action_ok = 0, srh_ok = 0, bpf_ok = 0;
> __u32 action = 0, table, iif, oif;
> struct ipv6_sr_hdr *srh;
> char **argv = *argvp;
> @@ -627,6 +686,18 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
> } else {
> continue;
> }
> + } else if (strcmp(*argv, "object-file") == 0 ||
> + strcmp(*argv, "obj") == 0 ||
> + strcmp(*argv, "object-pinned") == 0 ||
> + strcmp(*argv, "pinned") == 0 ||
> + strcmp(*argv, "fd") == 0) {
> + if (bpf_ok++) {
> + NEXT_ARG();
> + duparg2(*(argv-1), *argv);
> + }
> + if (lwt_parse_bpf(rta, len, &argc, &argv, SEG6_LOCAL_BPF,
> + BPF_PROG_TYPE_LWT_SEG6LOCAL) < 0)
> + exit(-1);
> } else {
> break;
> }
> @@ -896,55 +967,6 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
> return 0;
> }
>
> -struct lwt_x {
> - struct rtattr *rta;
> - size_t len;
> -};
> -
> -static void bpf_lwt_cb(void *lwt_ptr, int fd, const char *annotation)
> -{
> - struct lwt_x *x = lwt_ptr;
> -
> - rta_addattr32(x->rta, x->len, LWT_BPF_PROG_FD, fd);
> - rta_addattr_l(x->rta, x->len, LWT_BPF_PROG_NAME, annotation,
> - strlen(annotation) + 1);
> -}
> -
> -static const struct bpf_cfg_ops bpf_cb_ops = {
> - .ebpf_cb = bpf_lwt_cb,
> -};
> -
> -static int lwt_parse_bpf(struct rtattr *rta, size_t len,
> - int *argcp, char ***argvp,
> - int attr, const enum bpf_prog_type bpf_type)
> -{
> - struct bpf_cfg_in cfg = {
> - .type = bpf_type,
> - .argc = *argcp,
> - .argv = *argvp,
> - };
> - struct lwt_x x = {
> - .rta = rta,
> - .len = len,
> - };
> - struct rtattr *nest;
> - int err;
> -
> - nest = rta_nest(rta, len, attr);
> - err = bpf_parse_and_load_common(&cfg, &bpf_cb_ops, &x);
> - if (err < 0) {
> - fprintf(stderr, "Failed to parse eBPF program: %s\n",
> - strerror(-err));
> - return -1;
> - }
> - rta_nest_end(rta, nest);
> -
> - *argcp = cfg.argc;
> - *argvp = cfg.argv;
> -
> - return 0;
> -}
> -
> static void lwt_bpf_usage(void)
> {
> fprintf(stderr, "Usage: ip route ... encap bpf [ in BPF ] [ out BPF ] [ xmit BPF ] [...]\n");
> diff --git a/lib/bpf.c b/lib/bpf.c
> index 4e26c0df..65e26989 100644
> --- a/lib/bpf.c
> +++ b/lib/bpf.c
> @@ -95,6 +95,11 @@ static const struct bpf_prog_meta __bpf_prog_meta[] = {
> .subdir = "ip",
> .section = ELF_SECTION_PROG,
> },
> + [BPF_PROG_TYPE_LWT_SEG6LOCAL] = {
> + .type = "lwt_seg6local",
> + .subdir = "ip",
> + .section = ELF_SECTION_PROG,
> + },
> };
>
> static bool bpf_map_offload_neutral(enum bpf_map_type type)
> --
> 2.16.1
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH iproute2] ip: add support for seg6local End.BPF action
@ 2018-07-16 14:47 Mathieu Xhonneux
2018-07-16 12:51 ` Mathieu Xhonneux
2018-07-16 14:48 ` Stephen Hemminger
0 siblings, 2 replies; 3+ messages in thread
From: Mathieu Xhonneux @ 2018-07-16 14:47 UTC (permalink / raw)
To: netdev; +Cc: stephen, dsahern, dlebrun
This patch adds support for the End.BPF action of the seg6local
lightweight tunnel. Functions from the BPF lightweight tunnel are
re-used in this patch. Example:
$ ip -6 route add fc00::18 encap seg6local action End.BPF obj my_bpf.o
sec my_func dev eth0
$ ip -6 route show fc00::18
fc00::18 encap seg6local action End.BPF my_bpf.o:[my_func] dev eth0
metric 1024 pref medium
Signed-off-by: Mathieu Xhonneux <m.xhonneux@gmail.com>
---
ip/iproute_lwtunnel.c | 122 +++++++++++++++++++++++++++++---------------------
lib/bpf.c | 5 +++
2 files changed, 77 insertions(+), 50 deletions(-)
diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
index 46a212c8..71c3d8a4 100644
--- a/ip/iproute_lwtunnel.c
+++ b/ip/iproute_lwtunnel.c
@@ -177,6 +177,7 @@ static const char *seg6_action_names[SEG6_LOCAL_ACTION_MAX + 1] = {
[SEG6_LOCAL_ACTION_END_S] = "End.S",
[SEG6_LOCAL_ACTION_END_AS] = "End.AS",
[SEG6_LOCAL_ACTION_END_AM] = "End.AM",
+ [SEG6_LOCAL_ACTION_END_BPF] = "End.BPF",
};
static const char *format_action_type(int action)
@@ -250,6 +251,15 @@ static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
print_string(PRINT_ANY, "oif",
"oif %s ", ll_index_to_name(oif));
}
+
+ if (tb[SEG6_LOCAL_BPF]) {
+ struct rtattr *tb_bpf[LWT_BPF_PROG_MAX+1];
+
+ parse_rtattr_nested(tb_bpf, LWT_BPF_PROG_MAX, tb[SEG6_LOCAL_BPF]);
+
+ if (tb_bpf[LWT_BPF_PROG_NAME])
+ fprintf(fp, "%s ", rta_getattr_str(tb_bpf[LWT_BPF_PROG_NAME]));
+ }
}
static void print_encap_mpls(FILE *fp, struct rtattr *encap)
@@ -546,11 +556,60 @@ static int parse_encap_seg6(struct rtattr *rta, size_t len, int *argcp,
return 0;
}
+struct lwt_x {
+ struct rtattr *rta;
+ size_t len;
+};
+
+static void bpf_lwt_cb(void *lwt_ptr, int fd, const char *annotation)
+{
+ struct lwt_x *x = lwt_ptr;
+
+ rta_addattr32(x->rta, x->len, LWT_BPF_PROG_FD, fd);
+ rta_addattr_l(x->rta, x->len, LWT_BPF_PROG_NAME, annotation,
+ strlen(annotation) + 1);
+}
+
+static const struct bpf_cfg_ops bpf_cb_ops = {
+ .ebpf_cb = bpf_lwt_cb,
+};
+
+static int lwt_parse_bpf(struct rtattr *rta, size_t len,
+ int *argcp, char ***argvp,
+ int attr, const enum bpf_prog_type bpf_type)
+{
+ struct bpf_cfg_in cfg = {
+ .type = bpf_type,
+ .argc = *argcp,
+ .argv = *argvp,
+ };
+ struct lwt_x x = {
+ .rta = rta,
+ .len = len,
+ };
+ struct rtattr *nest;
+ int err;
+
+ nest = rta_nest(rta, len, attr);
+ err = bpf_parse_and_load_common(&cfg, &bpf_cb_ops, &x);
+ if (err < 0) {
+ fprintf(stderr, "Failed to parse eBPF program: %s\n",
+ strerror(-err));
+ return -1;
+ }
+ rta_nest_end(rta, nest);
+
+ *argcp = cfg.argc;
+ *argvp = cfg.argv;
+
+ return 0;
+}
+
static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
char ***argvp)
{
int segs_ok = 0, hmac_ok = 0, table_ok = 0, nh4_ok = 0, nh6_ok = 0;
- int iif_ok = 0, oif_ok = 0, action_ok = 0, srh_ok = 0;
+ int iif_ok = 0, oif_ok = 0, action_ok = 0, srh_ok = 0, bpf_ok = 0;
__u32 action = 0, table, iif, oif;
struct ipv6_sr_hdr *srh;
char **argv = *argvp;
@@ -627,6 +686,18 @@ static int parse_encap_seg6local(struct rtattr *rta, size_t len, int *argcp,
} else {
continue;
}
+ } else if (strcmp(*argv, "object-file") == 0 ||
+ strcmp(*argv, "obj") == 0 ||
+ strcmp(*argv, "object-pinned") == 0 ||
+ strcmp(*argv, "pinned") == 0 ||
+ strcmp(*argv, "fd") == 0) {
+ if (bpf_ok++) {
+ NEXT_ARG();
+ duparg2(*(argv-1), *argv);
+ }
+ if (lwt_parse_bpf(rta, len, &argc, &argv, SEG6_LOCAL_BPF,
+ BPF_PROG_TYPE_LWT_SEG6LOCAL) < 0)
+ exit(-1);
} else {
break;
}
@@ -896,55 +967,6 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len,
return 0;
}
-struct lwt_x {
- struct rtattr *rta;
- size_t len;
-};
-
-static void bpf_lwt_cb(void *lwt_ptr, int fd, const char *annotation)
-{
- struct lwt_x *x = lwt_ptr;
-
- rta_addattr32(x->rta, x->len, LWT_BPF_PROG_FD, fd);
- rta_addattr_l(x->rta, x->len, LWT_BPF_PROG_NAME, annotation,
- strlen(annotation) + 1);
-}
-
-static const struct bpf_cfg_ops bpf_cb_ops = {
- .ebpf_cb = bpf_lwt_cb,
-};
-
-static int lwt_parse_bpf(struct rtattr *rta, size_t len,
- int *argcp, char ***argvp,
- int attr, const enum bpf_prog_type bpf_type)
-{
- struct bpf_cfg_in cfg = {
- .type = bpf_type,
- .argc = *argcp,
- .argv = *argvp,
- };
- struct lwt_x x = {
- .rta = rta,
- .len = len,
- };
- struct rtattr *nest;
- int err;
-
- nest = rta_nest(rta, len, attr);
- err = bpf_parse_and_load_common(&cfg, &bpf_cb_ops, &x);
- if (err < 0) {
- fprintf(stderr, "Failed to parse eBPF program: %s\n",
- strerror(-err));
- return -1;
- }
- rta_nest_end(rta, nest);
-
- *argcp = cfg.argc;
- *argvp = cfg.argv;
-
- return 0;
-}
-
static void lwt_bpf_usage(void)
{
fprintf(stderr, "Usage: ip route ... encap bpf [ in BPF ] [ out BPF ] [ xmit BPF ] [...]\n");
diff --git a/lib/bpf.c b/lib/bpf.c
index 4e26c0df..65e26989 100644
--- a/lib/bpf.c
+++ b/lib/bpf.c
@@ -95,6 +95,11 @@ static const struct bpf_prog_meta __bpf_prog_meta[] = {
.subdir = "ip",
.section = ELF_SECTION_PROG,
},
+ [BPF_PROG_TYPE_LWT_SEG6LOCAL] = {
+ .type = "lwt_seg6local",
+ .subdir = "ip",
+ .section = ELF_SECTION_PROG,
+ },
};
static bool bpf_map_offload_neutral(enum bpf_map_type type)
--
2.16.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH iproute2] ip: add support for seg6local End.BPF action
2018-07-16 14:47 [PATCH iproute2] ip: add support for seg6local End.BPF action Mathieu Xhonneux
2018-07-16 12:51 ` Mathieu Xhonneux
@ 2018-07-16 14:48 ` Stephen Hemminger
1 sibling, 0 replies; 3+ messages in thread
From: Stephen Hemminger @ 2018-07-16 14:48 UTC (permalink / raw)
To: Mathieu Xhonneux; +Cc: netdev, dsahern, dlebrun
On Mon, 16 Jul 2018 14:47:41 +0000
Mathieu Xhonneux <m.xhonneux@gmail.com> wrote:
> This patch adds support for the End.BPF action of the seg6local
> lightweight tunnel. Functions from the BPF lightweight tunnel are
> re-used in this patch. Example:
>
> $ ip -6 route add fc00::18 encap seg6local action End.BPF obj my_bpf.o
> sec my_func dev eth0
>
> $ ip -6 route show fc00::18
> fc00::18 encap seg6local action End.BPF my_bpf.o:[my_func] dev eth0
> metric 1024 pref medium
>
> Signed-off-by: Mathieu Xhonneux <m.xhonneux@gmail.com>
> ---
> ip/iproute_lwtunnel.c | 122 +++++++++++++++++++++++++++++---------------------
> lib/bpf.c | 5 +++
> 2 files changed, 77 insertions(+), 50 deletions(-)
>
> diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c
> index 46a212c8..71c3d8a4 100644
> --- a/ip/iproute_lwtunnel.c
> +++ b/ip/iproute_lwtunnel.c
> @@ -177,6 +177,7 @@ static const char *seg6_action_names[SEG6_LOCAL_ACTION_MAX + 1] = {
> [SEG6_LOCAL_ACTION_END_S] = "End.S",
> [SEG6_LOCAL_ACTION_END_AS] = "End.AS",
> [SEG6_LOCAL_ACTION_END_AM] = "End.AM",
> + [SEG6_LOCAL_ACTION_END_BPF] = "End.BPF",
> };
>
> static const char *format_action_type(int action)
> @@ -250,6 +251,15 @@ static void print_encap_seg6local(FILE *fp, struct rtattr *encap)
> print_string(PRINT_ANY, "oif",
> "oif %s ", ll_index_to_name(oif));
> }
> +
> + if (tb[SEG6_LOCAL_BPF]) {
> + struct rtattr *tb_bpf[LWT_BPF_PROG_MAX+1];
> +
> + parse_rtattr_nested(tb_bpf, LWT_BPF_PROG_MAX, tb[SEG6_LOCAL_BPF]);
> +
> + if (tb_bpf[LWT_BPF_PROG_NAME])
> + fprintf(fp, "%s ", rta_getattr_str(tb_bpf[LWT_BPF_PROG_NAME]));
> + }
> }
Please use print_string to support JSON output.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-07-16 15:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-07-16 14:47 [PATCH iproute2] ip: add support for seg6local End.BPF action Mathieu Xhonneux
2018-07-16 12:51 ` Mathieu Xhonneux
2018-07-16 14:48 ` Stephen Hemminger
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.