The kernel supports passing the XFRMA_SA_PCPU attribute when creating a state (via NEWSA or ALLOCSPI). Add a "pcpu-num" argument, and print XFRMA_SA_PCPU when the kernel provides it. Signed-off-by: Sabrina Dubroca --- ip/ipxfrm.c | 6 ++++++ ip/xfrm_state.c | 20 ++++++++++++++++++-- man/man8/ip-xfrm.8 | 4 ++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c index b15cc0002e5b..586d24fb8594 100644 --- a/ip/ipxfrm.c +++ b/ip/ipxfrm.c @@ -919,6 +919,12 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, FILE *fp, fprintf(fp, "other (%d)", dir); fprintf(fp, "%s", _SL_); } + if (tb[XFRMA_SA_PCPU]) { + __u32 pcpu_num = rta_getattr_u32(tb[XFRMA_SA_PCPU]); + + fprintf(fp, "\tpcpu-num %u", pcpu_num); + fprintf(fp, "%s", _SL_); + } } static int xfrm_selector_iszero(struct xfrm_selector *s) diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c index fbb1f9137183..cf8e7f3ca0ce 100644 --- a/ip/xfrm_state.c +++ b/ip/xfrm_state.c @@ -47,9 +47,9 @@ static void usage(void) " [ coa ADDR[/PLEN] ] [ ctx CTX ] [ extra-flag EXTRA-FLAG-LIST ]\n" " [ offload [ crypto | packet ] dev DEV dir DIR ]\n" " [ output-mark OUTPUT-MARK [ mask MASK ] ]\n" - " [ if_id IF_ID ] [ tfcpad LENGTH ]\n" + " [ if_id IF_ID ] [ tfcpad LENGTH ] [ pcpu-num CPUNUM ]\n" "Usage: ip xfrm state allocspi ID [ mode MODE ] [ mark MARK [ mask MASK ] ]\n" - " [ reqid REQID ] [ dir DIR ] [ seq SEQ ] [ min SPI max SPI ]\n" + " [ reqid REQID ] [ dir DIR ] [ seq SEQ ] [ min SPI max SPI ] [ pcpu-num CPUNUM ]\n" "Usage: ip xfrm state { delete | get } ID [ mark MARK [ mask MASK ] ]\n" "Usage: ip xfrm state deleteall [ ID ] [ mode MODE ] [ reqid REQID ]\n" " [ flag FLAG-LIST ]\n" @@ -309,6 +309,7 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv) bool is_if_id_set = false; __u32 if_id = 0; __u32 tfcpad = 0; + __u32 pcpu_num = -1; while (argc > 0) { if (strcmp(*argv, "mode") == 0) { @@ -458,6 +459,10 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv) } else if (strcmp(*argv, "dir") == 0) { NEXT_ARG(); xfrm_dir_parse(&dir, &argc, &argv); + } else if (strcmp(*argv, "pcpu-num") == 0) { + NEXT_ARG(); + if (get_u32(&pcpu_num, *argv, 0)) + invarg("value after \"pcpu-num\" is invalid", *argv); } else { /* try to assume ALGO */ int type = xfrm_algotype_getbyname(*argv); @@ -767,6 +772,9 @@ static int xfrm_state_modify(int cmd, unsigned int flags, int argc, char **argv) } } + if (pcpu_num != -1) + addattr32(&req.n, sizeof(req.buf), XFRMA_SA_PCPU, pcpu_num); + if (req.xsinfo.family == AF_UNSPEC) req.xsinfo.family = AF_INET; @@ -797,6 +805,7 @@ static int xfrm_state_allocspi(int argc, char **argv) struct xfrm_mark mark = {0, 0}; struct nlmsghdr *answer; __u8 dir = 0; + __u32 pcpu_num = -1; while (argc > 0) { if (strcmp(*argv, "mode") == 0) { @@ -831,6 +840,10 @@ static int xfrm_state_allocspi(int argc, char **argv) } else if (strcmp(*argv, "dir") == 0) { NEXT_ARG(); xfrm_dir_parse(&dir, &argc, &argv); + } else if (strcmp(*argv, "pcpu-num") == 0) { + NEXT_ARG(); + if (get_u32(&pcpu_num, *argv, 0)) + invarg("value after \"pcpu-num\" is invalid", *argv); } else { /* try to assume ID */ if (idp) @@ -901,6 +914,9 @@ static int xfrm_state_allocspi(int argc, char **argv) } } + if (pcpu_num != -1) + addattr32(&req.n, sizeof(req.buf), XFRMA_SA_PCPU, pcpu_num); + if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0) exit(1); diff --git a/man/man8/ip-xfrm.8 b/man/man8/ip-xfrm.8 index 3efd617247d7..4c278ccba38c 100644 --- a/man/man8/ip-xfrm.8 +++ b/man/man8/ip-xfrm.8 @@ -76,6 +76,8 @@ ip-xfrm \- transform configuration .IR DIR " ]" .RB "[ " tfcpad .IR LENGTH " ]" +.RB "[ " pcpu-num +.IR CPUNUM " ]" .ti -8 .B "ip xfrm state allocspi" @@ -94,6 +96,8 @@ ip-xfrm \- transform configuration .I SPI .B max .IR SPI " ]" +.RB "[ " pcpu-num +.IR CPUNUM " ]" .ti -8 .BR "ip xfrm state" " { " delete " | " get " } " -- 2.51.1