RULE_SUP_PREFIXLEN,
RULE_UIDRANGE,
RULE_IPPROTO,
+ RULE_SPORT,
+ RULE_DPORT,
RULE_DISABLED,
__RULE_MAX
};
[RULE_ACTION] = { .name = "action", .type = BLOBMSG_TYPE_STRING },
[RULE_GOTO] = { .name = "goto", .type = BLOBMSG_TYPE_INT32 },
[RULE_IPPROTO] = { .name = "ipproto", .type = BLOBMSG_TYPE_STRING },
+ [RULE_SPORT] = { .name = "sport", .type = BLOBMSG_TYPE_STRING },
+ [RULE_DPORT] = { .name = "dport", .type = BLOBMSG_TYPE_STRING },
[RULE_DISABLED] = { .name = "disabled", .type = BLOBMSG_TYPE_BOOL },
};
rule->flags |= IPRULE_IPPROTO;
}
+ if ((cur = tb[RULE_SPORT]) != NULL) {
+ int ret = sscanf(blobmsg_get_string(cur), "%u-%u", &rule->sport_start, &rule->sport_end);
+
+ if (ret == 1)
+ rule->sport_end = rule->sport_start;
+ else if (ret != 2) {
+ D(INTERFACE, "Failed to parse sport range: %s", (char *) blobmsg_data(cur));
+ goto error;
+ }
+ rule->flags |= IPRULE_SPORT;
+ }
+
+ if ((cur = tb[RULE_DPORT]) != NULL) {
+ int ret = sscanf(blobmsg_get_string(cur), "%u-%u", &rule->dport_start, &rule->dport_end);
+
+ if (ret == 1)
+ rule->dport_end = rule->dport_start;
+ else if (ret != 2) {
+ D(INTERFACE, "Failed to parse dport range: %s", (char *) blobmsg_data(cur));
+ goto error;
+ }
+ rule->flags |= IPRULE_DPORT;
+ }
+
vlist_add(&iprules, &rule->node, rule);
return;
/* rule specifies ipproto */
IPRULE_IPPROTO = (1 << 15),
+
+ /* rule specifies sport */
+ IPRULE_SPORT = (1 << 16),
+
+ /* rule specifies dport */
+ IPRULE_DPORT = (1 << 17),
};
struct iprule {
unsigned int action;
unsigned int gotoid;
unsigned int ipproto;
+ unsigned int sport_start;
+ unsigned int sport_end;
+ unsigned int dport_start;
+ unsigned int dport_end;
};
extern struct vlist_tree iprules;
if (rule->flags & IPRULE_IPPROTO)
nla_put_u8(msg, FRA_IP_PROTO, rule->ipproto);
+ if (rule->flags & IPRULE_SPORT) {
+ struct fib_rule_port_range sportrange = {
+ .start = rule->sport_start,
+ .end = rule->sport_end
+ };
+
+ nla_put(msg, FRA_SPORT_RANGE, sizeof(sportrange), &sportrange);
+ }
+
+ if (rule->flags & IPRULE_DPORT) {
+ struct fib_rule_port_range dportrange = {
+ .start = rule->dport_start,
+ .end = rule->dport_end
+ };
+
+ nla_put(msg, FRA_DPORT_RANGE, sizeof(dportrange), &dportrange);
+ }
+
return system_rtnl_call(msg);
}