@@ -688,8 +688,8 @@ done:
return 0;
}
-void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
- FILE *fp, const char *prefix, bool nokeys)
+void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, FILE *fp,
+ const char *prefix, bool nokeys, bool dir)
{
if (tb[XFRMA_MARK]) {
struct rtattr *rta = tb[XFRMA_MARK];
@@ -895,9 +895,12 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
xuo = (struct xfrm_user_offload *)
RTA_DATA(tb[XFRMA_OFFLOAD_DEV]);
- fprintf(fp, "dev %s dir %s mode %s",
- ll_index_to_name(xuo->ifindex),
- (xuo->flags & XFRM_OFFLOAD_INBOUND) ? "in" : "out",
+ fprintf(fp, "dev %s ",
+ ll_index_to_name(xuo->ifindex));
+ if (dir)
+ fprintf(fp, "dir %s ",
+ (xuo->flags & XFRM_OFFLOAD_INBOUND) ? "in" : "out");
+ fprintf(fp, "mode %s",
(xuo->flags & XFRM_OFFLOAD_PACKET) ? "packet" : "crypto");
fprintf(fp, "%s", _SL_);
}
@@ -990,7 +993,7 @@ void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
fprintf(fp, " (0x%s)", strxf_mask8(xsinfo->flags));
fprintf(fp, "%s", _SL_);
- xfrm_xfrma_print(tb, xsinfo->family, fp, buf, nokeys);
+ xfrm_xfrma_print(tb, xsinfo->family, fp, buf, nokeys, true);
if (!xfrm_selector_iszero(&xsinfo->sel)) {
char sbuf[STRBUF_SIZE];
@@ -1096,7 +1099,7 @@ void xfrm_policy_info_print(struct xfrm_userpolicy_info *xpinfo,
if (show_stats > 0)
xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, buf);
- xfrm_xfrma_print(tb, xpinfo->sel.family, fp, buf, false);
+ xfrm_xfrma_print(tb, xpinfo->sel.family, fp, buf, false, false);
}
int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family,
@@ -124,8 +124,8 @@ const char *strxf_proto(__u8 proto);
const char *strxf_ptype(__u8 ptype);
void xfrm_selector_print(struct xfrm_selector *sel, __u16 family,
FILE *fp, const char *prefix);
-void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
- FILE *fp, const char *prefix, bool nokeys);
+void xfrm_xfrma_print(struct rtattr *tb[], __u16 family, FILE *fp,
+ const char *prefix, bool nokeys, bool dir);
void xfrm_state_info_print(struct xfrm_usersa_info *xsinfo,
struct rtattr *tb[], FILE *fp, const char *prefix,
const char *title, bool nokeys);
@@ -199,7 +199,7 @@ static int xfrm_report_print(struct nlmsghdr *n, void *arg)
parse_rtattr(tb, XFRMA_MAX, XFRMREP_RTA(xrep), len);
- xfrm_xfrma_print(tb, family, fp, " ", nokeys);
+ xfrm_xfrma_print(tb, family, fp, " ", nokeys, true);
if (oneline)
fprintf(fp, "\n");
@@ -57,6 +57,7 @@ static void usage(void)
" [ mark MARK [ mask MASK ] ] [ index INDEX ] [ ptype PTYPE ]\n"
" [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ]\n"
" [ if_id IF_ID ] [ LIMIT-LIST ] [ TMPL-LIST ]\n"
+ " [ offload packet dev DEV] } ]\n"
"Usage: ip xfrm policy { delete | get } { SELECTOR | index INDEX } dir DIR\n"
" [ ctx CTX ] [ mark MARK [ mask MASK ] ] [ ptype PTYPE ]\n"
" [ if_id IF_ID ]\n"
@@ -260,6 +261,7 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argv
char *ptypep = NULL;
char *sctxp = NULL;
struct xfrm_userpolicy_type upt = {};
+ struct xfrm_user_offload xuo = {};
char tmpls_buf[XFRM_TMPLS_BUF_SIZE] = {};
int tmpls_len = 0;
struct xfrm_mark mark = {0, 0};
@@ -268,6 +270,8 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argv
char str[CTX_BUF_SIZE];
} ctx = {};
bool is_if_id_set = false;
+ unsigned int ifindex = 0;
+ bool is_offload = false;
__u32 if_id = 0;
while (argc > 0) {
@@ -342,6 +346,21 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argv
if (get_u32(&if_id, *argv, 0))
invarg("IF_ID value is invalid", *argv);
is_if_id_set = true;
+ } else if (strcmp(*argv, "offload") == 0) {
+ NEXT_ARG();
+ if (strcmp(*argv, "packet") == 0)
+ NEXT_ARG();
+ else
+ invarg("Invalid offload mode", *argv);
+
+ if (strcmp(*argv, "dev") == 0) {
+ NEXT_ARG();
+ ifindex = ll_name_to_index(*argv);
+ if (!ifindex)
+ invarg("Invalid device name", *argv);
+ } else
+ invarg("Missing dev keyword", *argv);
+ is_offload = true;
} else {
if (selp)
duparg("unknown", *argv);
@@ -387,6 +406,13 @@ static int xfrm_policy_modify(int cmd, unsigned int flags, int argc, char **argv
if (is_if_id_set)
addattr32(&req.n, sizeof(req.buf), XFRMA_IF_ID, if_id);
+ if (is_offload) {
+ xuo.ifindex = ifindex;
+ xuo.flags |= XFRM_OFFLOAD_PACKET;
+ addattr_l(&req.n, sizeof(req.buf), XFRMA_OFFLOAD_DEV, &xuo,
+ sizeof(xuo));
+ }
+
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
exit(1);
@@ -252,6 +252,10 @@ ip-xfrm \- transform configuration
.IR FLAG-LIST " ]"
.RB "[ " if_id
.IR IF-ID " ]"
+.RB "[ " offload
+.RB packet
+.RB dev
+.IR DEV " ]"
.RI "[ " LIMIT-LIST " ] [ " TMPL-LIST " ]"
.ti -8
@@ -593,6 +597,10 @@ of the packets emitted by the state
.I IF-ID
xfrm interface identifier used to in both xfrm policies and states
+.TP
+.I DEV
+Network interface name used to offload policies and states
+
.sp
.PP
.TS