return 0;
printf("%s v%s, protocol version: %u\n",
program_name, program_version, IPSET_PROTOCOL);
+ /* Check kernel protocol version */
+ ipset_cmd(session, IPSET_CMD_NONE, 0);
+ if (ipset_session_report_type(session) != IPSET_NO_ERROR)
+ ipset->standard_error(ipset, p);
if (ipset->interactive)
return 0;
return ipset->custom_error(ipset, p, IPSET_NO_PROBLEM, NULL);
const struct ipset_type *saved_type; /* Saved type */
struct nlattr *nested[IPSET_NEST_MAX]; /* Pointer to nest levels */
uint8_t nestid; /* Current nest level */
+ uint8_t protocol; /* The protocol used */
bool version_checked; /* Version checked */
/* Output buffer */
char outbuf[IPSET_OUTBUFLEN]; /* Output buffer */
"while userspace supports protocol versions %u-%u",
min, max, IPSET_PROTOCOL_MIN, IPSET_PROTOCOL_MAX);
+ session->protocol = MIN(max, IPSET_PROTOCOL_MAX);
session->version_checked = true;
return MNL_CB_STOP;
proto = mnl_attr_get_u8(nla[IPSET_ATTR_PROTOCOL]);
/* Check protocol */
- if (cmd != IPSET_CMD_PROTOCOL && proto != IPSET_PROTOCOL)
+ if (cmd != IPSET_CMD_PROTOCOL && proto != session->protocol)
FAILURE("Giving up: kernel protocol version %u "
"does not match our protocol version %u",
- proto, IPSET_PROTOCOL);
+ proto, session->protocol);
D("Message: %s", cmd2name[cmd]);
switch (cmd) {
type, family, attrs);
}
-#define ADDATTR_PROTOCOL(nlh) \
- mnl_attr_put_u8(nlh, IPSET_ATTR_PROTOCOL, IPSET_PROTOCOL)
+#define ADDATTR_PROTOCOL(nlh, protocol) \
+ mnl_attr_put_u8(nlh, IPSET_ATTR_PROTOCOL, protocol)
#define ADDATTR(session, nlh, data, type, family, attrs) \
data2attr(session, nlh, data, type, family, attrs)
/* Initialize header */
session->transport->fill_hdr(session->handle, cmd, buffer, len, 0);
- ADDATTR_PROTOCOL(nlh);
+ ADDATTR_PROTOCOL(nlh,
+ cmd == IPSET_CMD_PROTOCOL ? IPSET_PROTOCOL : session->protocol);
switch (cmd) {
case IPSET_CMD_PROTOCOL:
session->buffer,
session->bufsize,
session->envopts);
- ADDATTR_PROTOCOL(nlh);
+ ADDATTR_PROTOCOL(nlh, session->protocol);
}
D("Protocol added, aggregate %s", aggregate ? "yes" : "no");
switch (session->cmd) {
assert(session);
- if (cmd <= IPSET_CMD_NONE || cmd >= IPSET_MSG_MAX)
+ if (cmd < IPSET_CMD_NONE || cmd >= IPSET_MSG_MAX)
return 0;
/* Initialize transport method if not done yet */
if (!session->version_checked) {
if (build_send_private_msg(session, IPSET_CMD_PROTOCOL) < 0)
return -1;
+ if (ipset_session_report_type(session) == IPSET_WARNING &&
+ cmd != IPSET_CMD_NONE)
+ /* Suppress protocol warning */
+ ipset_session_report_reset(session);
}
+ /* IPSET_CMD_NONE: check protocol version only */
+ if (cmd == IPSET_CMD_NONE)
+ return 0;
/* Private commands */
if (cmd == IPSET_CMD_TYPE || cmd == IPSET_CMD_HEADER)
session->buffer = session + 1;
session->istream = stdin;
session->ostream = stdout;
+ session->protocol = IPSET_PROTOCOL;
/* The single transport method yet */
session->transport = &ipset_mnl_transport;