1 /* SPDX-License-Identifier: GPL-2.0 */
4 #include <linux/if_ether.h>
5 #include <linux/if_link.h>
6 #include <linux/netlink.h>
7 #include <linux/rtnetlink.h>
9 #include "libnetlink.h"
12 #include "ip_common.h"
13 #include "json_print.h"
15 #define BAREUDP_ATTRSET(attrs, type) (((attrs) & (1L << (type))) != 0)
17 static void print_explain(FILE *f
)
20 "Usage: ... bareudp dstport PORT\n"
22 " [ srcportmin PORT ]\n"
23 " [ [no]multiproto ]\n"
25 "Where: PORT := UDP_PORT\n"
26 " PROTO := ETHERTYPE\n"
28 "Note: ETHERTYPE can be given as number or as protocol name (\"ipv4\", \"ipv6\",\n"
29 " \"mpls_uc\", etc.).\n"
33 static void explain(void)
35 print_explain(stderr
);
38 static void check_duparg(__u64
*attrs
, int type
, const char *key
,
41 if (!BAREUDP_ATTRSET(*attrs
, type
)) {
42 *attrs
|= (1L << type
);
48 static int bareudp_parse_opt(struct link_util
*lu
, int argc
, char **argv
,
51 bool multiproto
= false;
58 if (matches(*argv
, "dstport") == 0) {
60 check_duparg(&attrs
, IFLA_BAREUDP_PORT
, "dstport",
62 if (get_be16(&dstport
, *argv
, 0))
63 invarg("dstport", *argv
);
64 } else if (matches(*argv
, "ethertype") == 0) {
66 check_duparg(&attrs
, IFLA_BAREUDP_ETHERTYPE
,
68 if (ll_proto_a2n(ðertype
, *argv
))
69 invarg("ethertype", *argv
);
70 } else if (matches(*argv
, "srcportmin") == 0) {
72 check_duparg(&attrs
, IFLA_BAREUDP_SRCPORT_MIN
,
74 if (get_u16(&srcportmin
, *argv
, 0))
75 invarg("srcportmin", *argv
);
76 } else if (matches(*argv
, "multiproto") == 0) {
77 check_duparg(&attrs
, IFLA_BAREUDP_MULTIPROTO_MODE
,
80 } else if (matches(*argv
, "nomultiproto") == 0) {
81 check_duparg(&attrs
, IFLA_BAREUDP_MULTIPROTO_MODE
,
84 } else if (matches(*argv
, "help") == 0) {
88 fprintf(stderr
, "bareudp: unknown command \"%s\"?\n",
96 if (!BAREUDP_ATTRSET(attrs
, IFLA_BAREUDP_PORT
))
98 if (!BAREUDP_ATTRSET(attrs
, IFLA_BAREUDP_ETHERTYPE
))
101 addattr16(n
, 1024, IFLA_BAREUDP_PORT
, dstport
);
102 addattr16(n
, 1024, IFLA_BAREUDP_ETHERTYPE
, ethertype
);
103 if (BAREUDP_ATTRSET(attrs
, IFLA_BAREUDP_SRCPORT_MIN
))
104 addattr16(n
, 1024, IFLA_BAREUDP_SRCPORT_MIN
, srcportmin
);
106 addattr(n
, 1024, IFLA_BAREUDP_MULTIPROTO_MODE
);
111 static void bareudp_print_opt(struct link_util
*lu
, FILE *f
,
117 if (tb
[IFLA_BAREUDP_PORT
])
118 print_uint(PRINT_ANY
, "dstport", "dstport %u ",
119 rta_getattr_be16(tb
[IFLA_BAREUDP_PORT
]));
121 if (tb
[IFLA_BAREUDP_ETHERTYPE
]) {
122 struct rtattr
*attr
= tb
[IFLA_BAREUDP_ETHERTYPE
];
123 SPRINT_BUF(ethertype
);
125 print_string(PRINT_ANY
, "ethertype", "ethertype %s ",
126 ll_proto_n2a(rta_getattr_u16(attr
),
127 ethertype
, sizeof(ethertype
)));
130 if (tb
[IFLA_BAREUDP_SRCPORT_MIN
])
131 print_uint(PRINT_ANY
, "srcportmin", "srcportmin %u ",
132 rta_getattr_u16(tb
[IFLA_BAREUDP_SRCPORT_MIN
]));
134 if (tb
[IFLA_BAREUDP_MULTIPROTO_MODE
])
135 print_bool(PRINT_ANY
, "multiproto", "multiproto ", true);
137 print_bool(PRINT_ANY
, "multiproto", "nomultiproto ", false);
140 static void bareudp_print_help(struct link_util
*lu
, int argc
, char **argv
,
146 struct link_util bareudp_link_util
= {
148 .maxattr
= IFLA_BAREUDP_MAX
,
149 .parse_opt
= bareudp_parse_opt
,
150 .print_opt
= bareudp_print_opt
,
151 .print_help
= bareudp_print_help
,