mirror of
https://gitlab.alpinelinux.org/alpine/aports.git
synced 2025-10-15 09:21:32 +02:00
364 lines
12 KiB
Diff
364 lines
12 KiB
Diff
diff --git a/ip/ipxfrm.c b/ip/ipxfrm.c
|
|
index 7dc36f3..0aaf97a 100644
|
|
--- a/ip/ipxfrm.c
|
|
+++ b/ip/ipxfrm.c
|
|
@@ -629,9 +629,48 @@ static void xfrm_tmpl_print(struct xfrm_user_tmpl *tmpls, int len,
|
|
}
|
|
}
|
|
|
|
+int xfrm_parse_mark(struct xfrm_umark *mark, int *argcp, char ***argvp)
|
|
+{
|
|
+ int argc = *argcp;
|
|
+ char **argv = *argvp;
|
|
+
|
|
+ NEXT_ARG();
|
|
+ if (get_u32(&mark->v, *argv, 0)) {
|
|
+ invarg("Illegal \"mark\" value\n", *argv);
|
|
+ }
|
|
+ if (argc > 1)
|
|
+ NEXT_ARG();
|
|
+ else { /* last entry on parse line */
|
|
+ mark->m = 0xffffffff;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (strcmp(*argv, "mask") == 0) {
|
|
+ NEXT_ARG();
|
|
+ if (get_u32(&mark->m, *argv, 0)) {
|
|
+ invarg("Illegal \"mark\" mask\n", *argv);
|
|
+ }
|
|
+ } else {
|
|
+ mark->m = 0xffffffff;
|
|
+ PREV_ARG();
|
|
+ }
|
|
+
|
|
+done:
|
|
+ *argcp = argc;
|
|
+ *argvp = argv;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
|
|
FILE *fp, const char *prefix)
|
|
{
|
|
+ if (tb[XFRMA_MARK]) {
|
|
+ struct rtattr *rta = tb[XFRMA_MARK];
|
|
+ struct xfrm_umark *m = (struct xfrm_umark *) RTA_DATA(rta);
|
|
+ fprintf(fp, "\tmark %d/0x%x\n", m->v, m->m);
|
|
+ }
|
|
+
|
|
if (tb[XFRMA_ALG_AUTH]) {
|
|
struct rtattr *rta = tb[XFRMA_ALG_AUTH];
|
|
xfrm_algo_print((struct xfrm_algo *) RTA_DATA(rta),
|
|
@@ -740,6 +779,7 @@ void xfrm_xfrma_print(struct rtattr *tb[], __u16 family,
|
|
fprintf(fp, "%s", strxf_time(lastused));
|
|
fprintf(fp, "%s", _SL_);
|
|
}
|
|
+
|
|
}
|
|
|
|
static int xfrm_selector_iszero(struct xfrm_selector *s)
|
|
diff --git a/ip/xfrm.h b/ip/xfrm.h
|
|
index 104fb20..ab03b19 100644
|
|
--- a/ip/xfrm.h
|
|
+++ b/ip/xfrm.h
|
|
@@ -121,6 +121,7 @@ int xfrm_xfrmproto_is_ipsec(__u8 proto);
|
|
int xfrm_xfrmproto_is_ro(__u8 proto);
|
|
int xfrm_xfrmproto_getbyname(char *name);
|
|
int xfrm_algotype_getbyname(char *name);
|
|
+int xfrm_parse_mark(struct xfrm_umark *mark, int *argcp, char ***argvp);
|
|
const char *strxf_xfrmproto(__u8 proto);
|
|
const char *strxf_algotype(int type);
|
|
const char *strxf_mask8(__u8 mask);
|
|
diff --git a/ip/xfrm_policy.c b/ip/xfrm_policy.c
|
|
index 2788477..7cdf0b6 100644
|
|
--- a/ip/xfrm_policy.c
|
|
+++ b/ip/xfrm_policy.c
|
|
@@ -54,8 +54,8 @@ static void usage(void) __attribute__((noreturn));
|
|
static void usage(void)
|
|
{
|
|
fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ index INDEX ] [ ptype PTYPE ]\n");
|
|
- fprintf(stderr, " [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ] [ LIMIT-LIST ] [ TMPL-LIST ]\n");
|
|
- fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ] [ ptype PTYPE ]\n");
|
|
+ fprintf(stderr, " [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ] [ LIMIT-LIST ] [ TMPL-LIST ] [mark MARK [mask MASK]]\n");
|
|
+ fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ] [ ptype PTYPE ] [mark MARK [mask MASK]]\n");
|
|
fprintf(stderr, "Usage: ip xfrm policy { deleteall | list } [ dir DIR ] [ SELECTOR ]\n");
|
|
fprintf(stderr, " [ index INDEX ] [ action ACTION ] [ priority PRIORITY ] [ flag FLAG-LIST ]\n");
|
|
fprintf(stderr, "Usage: ip xfrm policy flush [ ptype PTYPE ]\n");
|
|
@@ -235,6 +235,7 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
|
|
struct xfrm_userpolicy_type upt;
|
|
char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
|
|
int tmpls_len = 0;
|
|
+ struct xfrm_umark mark = {0, 0};
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
memset(&upt, 0, sizeof(upt));
|
|
@@ -258,6 +259,8 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
|
|
|
|
NEXT_ARG();
|
|
xfrm_policy_dir_parse(&req.xpinfo.dir, &argc, &argv);
|
|
+ } else if (strcmp(*argv, "mark") == 0) {
|
|
+ xfrm_parse_mark(&mark, &argc, &argv);
|
|
} else if (strcmp(*argv, "index") == 0) {
|
|
NEXT_ARG();
|
|
if (get_u32(&req.xpinfo.index, *argv, 0))
|
|
@@ -334,6 +337,16 @@ static int xfrm_policy_modify(int cmd, unsigned flags, int argc, char **argv)
|
|
(void *)tmpls_buf, tmpls_len);
|
|
}
|
|
|
|
+ if (mark.m & mark.v) {
|
|
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
|
|
+ (void *)&mark, sizeof(mark));
|
|
+ if (r < 0) {
|
|
+ fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__);
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
|
|
exit(1);
|
|
|
|
@@ -515,6 +528,7 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
|
|
char *indexp = NULL;
|
|
char *ptypep = NULL;
|
|
struct xfrm_userpolicy_type upt;
|
|
+ struct xfrm_umark mark = {0, 0};
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
memset(&upt, 0, sizeof(upt));
|
|
@@ -532,6 +546,8 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
|
|
NEXT_ARG();
|
|
xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv);
|
|
|
|
+ } else if (strcmp(*argv, "mark") == 0) {
|
|
+ xfrm_parse_mark(&mark, &argc, &argv);
|
|
} else if (strcmp(*argv, "index") == 0) {
|
|
if (indexp)
|
|
duparg("index", *argv);
|
|
@@ -584,6 +600,15 @@ static int xfrm_policy_get_or_delete(int argc, char **argv, int delete,
|
|
if (req.xpid.sel.family == AF_UNSPEC)
|
|
req.xpid.sel.family = AF_INET;
|
|
|
|
+ if (mark.m & mark.v) {
|
|
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
|
|
+ (void *)&mark, sizeof(mark));
|
|
+ if (r < 0) {
|
|
+ fprintf(stderr, "%s: XFRMA_MARK failed\n",__func__);
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (rtnl_talk(&rth, &req.n, 0, 0, res_nlbuf, NULL, NULL) < 0)
|
|
exit(2);
|
|
|
|
@@ -951,26 +976,35 @@ static int xfrm_policy_flush(int argc, char **argv)
|
|
|
|
int do_xfrm_policy(int argc, char **argv)
|
|
{
|
|
+//Needs testing ..
|
|
if (argc < 1)
|
|
return xfrm_policy_list_or_deleteall(0, NULL, 0);
|
|
|
|
+//should work
|
|
if (matches(*argv, "add") == 0)
|
|
return xfrm_policy_modify(XFRM_MSG_NEWPOLICY, 0,
|
|
argc-1, argv+1);
|
|
+//should work
|
|
if (matches(*argv, "update") == 0)
|
|
return xfrm_policy_modify(XFRM_MSG_UPDPOLICY, 0,
|
|
argc-1, argv+1);
|
|
+//should work
|
|
if (matches(*argv, "delete") == 0)
|
|
return xfrm_policy_delete(argc-1, argv+1);
|
|
+//Needs fixing ..
|
|
if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
|
|
return xfrm_policy_list_or_deleteall(argc-1, argv+1, 1);
|
|
+//should work
|
|
if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
|
|
|| matches(*argv, "lst") == 0)
|
|
return xfrm_policy_list_or_deleteall(argc-1, argv+1, 0);
|
|
+//should work
|
|
if (matches(*argv, "get") == 0)
|
|
return xfrm_policy_get(argc-1, argv+1);
|
|
+//should work
|
|
if (matches(*argv, "flush") == 0)
|
|
return xfrm_policy_flush(argc-1, argv+1);
|
|
+//should work
|
|
if (matches(*argv, "count") == 0)
|
|
return xfrm_spd_getinfo(argc, argv);
|
|
if (matches(*argv, "help") == 0)
|
|
diff --git a/ip/xfrm_state.c b/ip/xfrm_state.c
|
|
index 32238ab..4255d25 100644
|
|
--- a/ip/xfrm_state.c
|
|
+++ b/ip/xfrm_state.c
|
|
@@ -67,7 +67,7 @@ static void usage(void)
|
|
fprintf(stderr, "Usage: ip xfrm state flush [ proto XFRM_PROTO ]\n");
|
|
fprintf(stderr, "Usage: ip xfrm state count \n");
|
|
|
|
- fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ]\n");
|
|
+ fprintf(stderr, "ID := [ src ADDR ] [ dst ADDR ] [ proto XFRM_PROTO ] [ spi SPI ] [mark MARK [mask MASK]]\n");
|
|
//fprintf(stderr, "XFRM_PROTO := [ esp | ah | comp ]\n");
|
|
fprintf(stderr, "XFRM_PROTO := [ ");
|
|
fprintf(stderr, "%s | ", strxf_xfrmproto(IPPROTO_ESP));
|
|
@@ -246,6 +246,7 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
|
|
char *aalgop = NULL;
|
|
char *calgop = NULL;
|
|
char *coap = NULL;
|
|
+ struct xfrm_umark mark = {0, 0};
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
memset(&replay, 0, sizeof(replay));
|
|
@@ -264,6 +265,8 @@ static int xfrm_state_modify(int cmd, unsigned flags, int argc, char **argv)
|
|
if (strcmp(*argv, "mode") == 0) {
|
|
NEXT_ARG();
|
|
xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv);
|
|
+ } else if (strcmp(*argv, "mark") == 0) {
|
|
+ xfrm_parse_mark(&mark, &argc, &argv);
|
|
} else if (strcmp(*argv, "reqid") == 0) {
|
|
NEXT_ARG();
|
|
xfrm_reqid_parse(&req.xsinfo.reqid, &argc, &argv);
|
|
@@ -440,6 +443,15 @@ parse_algo:
|
|
exit(1);
|
|
}
|
|
|
|
+ if (mark.m & mark.v) {
|
|
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
|
|
+ (void *)&mark, sizeof(mark));
|
|
+ if (r < 0) {
|
|
+ fprintf(stderr, "XFRMA_MARK failed\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+
|
|
switch (req.xsinfo.mode) {
|
|
case XFRM_MODE_TRANSPORT:
|
|
case XFRM_MODE_TUNNEL:
|
|
@@ -519,6 +531,7 @@ static int xfrm_state_allocspi(int argc, char **argv)
|
|
char *idp = NULL;
|
|
char *minp = NULL;
|
|
char *maxp = NULL;
|
|
+ struct xfrm_umark mark = {0, 0};
|
|
char res_buf[NLMSG_BUF_SIZE];
|
|
struct nlmsghdr *res_n = (struct nlmsghdr *)res_buf;
|
|
|
|
@@ -542,6 +555,8 @@ static int xfrm_state_allocspi(int argc, char **argv)
|
|
if (strcmp(*argv, "mode") == 0) {
|
|
NEXT_ARG();
|
|
xfrm_mode_parse(&req.xspi.info.mode, &argc, &argv);
|
|
+ } else if (strcmp(*argv, "mark") == 0) {
|
|
+ xfrm_parse_mark(&mark, &argc, &argv);
|
|
} else if (strcmp(*argv, "reqid") == 0) {
|
|
NEXT_ARG();
|
|
xfrm_reqid_parse(&req.xspi.info.reqid, &argc, &argv);
|
|
@@ -618,6 +633,15 @@ static int xfrm_state_allocspi(int argc, char **argv)
|
|
req.xspi.max = 0xffff;
|
|
}
|
|
|
|
+ if (mark.m & mark.v) {
|
|
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
|
|
+ (void *)&mark, sizeof(mark));
|
|
+ if (r < 0) {
|
|
+ fprintf(stderr, "XFRMA_MARK failed\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
|
|
exit(1);
|
|
|
|
@@ -763,6 +787,7 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
|
|
} req;
|
|
struct xfrm_id id;
|
|
char *idp = NULL;
|
|
+ struct xfrm_umark mark = {0, 0};
|
|
|
|
memset(&req, 0, sizeof(req));
|
|
|
|
@@ -774,26 +799,39 @@ static int xfrm_state_get_or_delete(int argc, char **argv, int delete)
|
|
while (argc > 0) {
|
|
xfrm_address_t saddr;
|
|
|
|
- if (idp)
|
|
- invarg("unknown", *argv);
|
|
- idp = *argv;
|
|
+ if (strcmp(*argv, "mark") == 0) {
|
|
+ xfrm_parse_mark(&mark, &argc, &argv);
|
|
+ } else {
|
|
+ if (idp)
|
|
+ invarg("unknown", *argv);
|
|
+ idp = *argv;
|
|
|
|
- /* ID */
|
|
- memset(&id, 0, sizeof(id));
|
|
- memset(&saddr, 0, sizeof(saddr));
|
|
- xfrm_id_parse(&saddr, &id, &req.xsid.family, 0,
|
|
- &argc, &argv);
|
|
+ /* ID */
|
|
+ memset(&id, 0, sizeof(id));
|
|
+ memset(&saddr, 0, sizeof(saddr));
|
|
+ xfrm_id_parse(&saddr, &id, &req.xsid.family, 0,
|
|
+ &argc, &argv);
|
|
|
|
- memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
|
|
- req.xsid.spi = id.spi;
|
|
- req.xsid.proto = id.proto;
|
|
+ memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
|
|
+ req.xsid.spi = id.spi;
|
|
+ req.xsid.proto = id.proto;
|
|
|
|
- addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
|
|
- (void *)&saddr, sizeof(saddr));
|
|
+ addattr_l(&req.n, sizeof(req.buf), XFRMA_SRCADDR,
|
|
+ (void *)&saddr, sizeof(saddr));
|
|
+ }
|
|
|
|
argc--; argv++;
|
|
}
|
|
|
|
+ if (mark.m & mark.v) {
|
|
+ int r = addattr_l(&req.n, sizeof(req.buf), XFRMA_MARK,
|
|
+ (void *)&mark, sizeof(mark));
|
|
+ if (r < 0) {
|
|
+ fprintf(stderr, "XFRMA_MARK failed\n");
|
|
+ exit(1);
|
|
+ }
|
|
+ }
|
|
+
|
|
if (rtnl_open_byproto(&rth, 0, NETLINK_XFRM) < 0)
|
|
exit(1);
|
|
|
|
@@ -1117,23 +1155,31 @@ int do_xfrm_state(int argc, char **argv)
|
|
if (argc < 1)
|
|
return xfrm_state_list_or_deleteall(0, NULL, 0);
|
|
|
|
+ //XXX: should work
|
|
if (matches(*argv, "add") == 0)
|
|
return xfrm_state_modify(XFRM_MSG_NEWSA, 0,
|
|
argc-1, argv+1);
|
|
+ //XXX: should work
|
|
if (matches(*argv, "update") == 0)
|
|
return xfrm_state_modify(XFRM_MSG_UPDSA, 0,
|
|
argc-1, argv+1);
|
|
+ //XXX: should work
|
|
if (matches(*argv, "allocspi") == 0)
|
|
return xfrm_state_allocspi(argc-1, argv+1);
|
|
+ //XXX: should work
|
|
if (matches(*argv, "delete") == 0)
|
|
return xfrm_state_get_or_delete(argc-1, argv+1, 1);
|
|
+ //XXX: needs testing ..
|
|
if (matches(*argv, "deleteall") == 0 || matches(*argv, "delall") == 0)
|
|
return xfrm_state_list_or_deleteall(argc-1, argv+1, 1);
|
|
+ //XXX: should work
|
|
if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
|
|
|| matches(*argv, "lst") == 0)
|
|
return xfrm_state_list_or_deleteall(argc-1, argv+1, 0);
|
|
+ //XXX: should work
|
|
if (matches(*argv, "get") == 0)
|
|
return xfrm_state_get_or_delete(argc-1, argv+1, 0);
|
|
+ //XXX: should work
|
|
if (matches(*argv, "flush") == 0)
|
|
return xfrm_state_flush(argc-1, argv+1);
|
|
if (matches(*argv, "count") == 0) {
|