|
34 | 34 | #define FLOWER_ATTR_IP_PROTO (1 << 16) |
35 | 35 | #define FLOWER_ATTR_IP_TTL (1 << 17) |
36 | 36 | #define FLOWER_ATTR_IP_TTL_MASK (1 << 18) |
| 37 | +#define FLOWER_ATTR_SRC_PORT_MIN (1 << 19) |
| 38 | +#define FLOWER_ATTR_SRC_PORT_MAX (1 << 20) |
| 39 | +#define FLOWER_ATTR_DST_PORT_MIN (1 << 21) |
| 40 | +#define FLOWER_ATTR_DST_PORT_MAX (1 << 22) |
| 41 | + |
37 | 42 | /** @endcond */ |
38 | 43 |
|
39 | 44 | #define FLOWER_DSCP_MAX 0xe0 |
@@ -172,6 +177,26 @@ static int flower_msg_parser(struct rtnl_tc *tc, void *data) |
172 | 177 | f->cf_mask |= FLOWER_ATTR_IP_PROTO; |
173 | 178 | } |
174 | 179 |
|
| 180 | + if (tb[TCA_FLOWER_KEY_PORT_SRC_MIN]) { |
| 181 | + f->cf_src_port_min = nla_get_u16(tb[TCA_FLOWER_KEY_PORT_SRC_MIN]); |
| 182 | + f->cf_mask |= FLOWER_ATTR_SRC_PORT_MIN; |
| 183 | + } |
| 184 | + |
| 185 | + if (tb[TCA_FLOWER_KEY_PORT_SRC_MAX]) { |
| 186 | + f->cf_src_port_max = nla_get_u16(tb[TCA_FLOWER_KEY_PORT_SRC_MAX]); |
| 187 | + f->cf_mask |= FLOWER_ATTR_SRC_PORT_MAX; |
| 188 | + } |
| 189 | + |
| 190 | + if (tb[TCA_FLOWER_KEY_PORT_DST_MIN]) { |
| 191 | + f->cf_dst_port_min = nla_get_u16(tb[TCA_FLOWER_KEY_PORT_DST_MIN]); |
| 192 | + f->cf_mask |= FLOWER_ATTR_DST_PORT_MIN; |
| 193 | + } |
| 194 | + |
| 195 | + if (tb[TCA_FLOWER_KEY_PORT_DST_MAX]) { |
| 196 | + f->cf_dst_port_max = nla_get_u16(tb[TCA_FLOWER_KEY_PORT_DST_MAX]); |
| 197 | + f->cf_mask |= FLOWER_ATTR_DST_PORT_MAX; |
| 198 | + } |
| 199 | + |
175 | 200 | return 0; |
176 | 201 | } |
177 | 202 |
|
@@ -245,6 +270,18 @@ static int flower_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg) |
245 | 270 | if (f->cf_mask & FLOWER_ATTR_IP_PROTO) |
246 | 271 | NLA_PUT_U8(msg, TCA_FLOWER_KEY_IP_PROTO, f->cf_ip_proto); |
247 | 272 |
|
| 273 | + if (f->cf_mask & FLOWER_ATTR_SRC_PORT_MIN) |
| 274 | + NLA_PUT_U16(msg, TCA_FLOWER_KEY_PORT_SRC_MIN, f->cf_src_port_min); |
| 275 | + |
| 276 | + if (f->cf_mask & FLOWER_ATTR_SRC_PORT_MAX) |
| 277 | + NLA_PUT_U16(msg, TCA_FLOWER_KEY_PORT_SRC_MAX, f->cf_src_port_max); |
| 278 | + |
| 279 | + if (f->cf_mask & FLOWER_ATTR_DST_PORT_MIN) |
| 280 | + NLA_PUT_U16(msg, TCA_FLOWER_KEY_PORT_DST_MIN, f->cf_dst_port_min); |
| 281 | + |
| 282 | + if (f->cf_mask & FLOWER_ATTR_DST_PORT_MIN) |
| 283 | + NLA_PUT_U16(msg, TCA_FLOWER_KEY_PORT_DST_MAX, f->cf_dst_port_max); |
| 284 | + |
248 | 285 | return 0; |
249 | 286 |
|
250 | 287 | nla_put_failure: |
@@ -1045,6 +1082,94 @@ int rtnl_flower_get_flags(struct rtnl_cls *cls, int *flags) |
1045 | 1082 | return 0; |
1046 | 1083 | } |
1047 | 1084 |
|
| 1085 | +int rtnl_flower_set_src_port_range(struct rtnl_cls *cls, uint16_t min, uint16_t max) |
| 1086 | +{ |
| 1087 | + struct rtnl_flower *f = rtnl_tc_data(TC_CAST(cls)); |
| 1088 | + |
| 1089 | + if (!f) |
| 1090 | + return -NLE_NOMEM; |
| 1091 | + |
| 1092 | + if (min) { |
| 1093 | + f->cf_src_port_min = htons(min); |
| 1094 | + f->cf_mask |= FLOWER_ATTR_SRC_PORT_MIN; |
| 1095 | + } |
| 1096 | + |
| 1097 | + if (max) { |
| 1098 | + f->cf_src_port_max = htons(max); |
| 1099 | + f->cf_mask |= FLOWER_ATTR_SRC_PORT_MAX; |
| 1100 | + } |
| 1101 | + |
| 1102 | + return 0; |
| 1103 | +} |
| 1104 | + |
| 1105 | +int rtnl_flower_set_dst_port_range(struct rtnl_cls *cls, uint16_t min, uint16_t max) |
| 1106 | +{ |
| 1107 | + struct rtnl_flower *f = rtnl_tc_data(TC_CAST(cls)); |
| 1108 | + |
| 1109 | + if (!f) |
| 1110 | + return -NLE_NOMEM; |
| 1111 | + |
| 1112 | + if (min) { |
| 1113 | + f->cf_dst_port_min = htons(min); |
| 1114 | + f->cf_mask |= FLOWER_ATTR_DST_PORT_MIN; |
| 1115 | + } |
| 1116 | + |
| 1117 | + if (max) { |
| 1118 | + f->cf_dst_port_max = htons(max); |
| 1119 | + f->cf_mask |= FLOWER_ATTR_DST_PORT_MAX; |
| 1120 | + } |
| 1121 | + |
| 1122 | + return 0; |
| 1123 | +} |
| 1124 | + |
| 1125 | +int rtnl_flower_get_src_port_range(struct rtnl_cls *cls, uint16_t *min, uint16_t *max) |
| 1126 | +{ |
| 1127 | + struct rtnl_flower *f = rtnl_tc_data_peek(TC_CAST(cls)); |
| 1128 | + |
| 1129 | + if (!f) |
| 1130 | + return -NLE_INVAL; |
| 1131 | + |
| 1132 | + if (min) { |
| 1133 | + if (f->cf_mask & FLOWER_ATTR_SRC_PORT_MIN) |
| 1134 | + *min = ntohs(f->cf_src_port_min); |
| 1135 | + else |
| 1136 | + *min = 0; |
| 1137 | + } |
| 1138 | + |
| 1139 | + if (max) { |
| 1140 | + if (f->cf_mask & FLOWER_ATTR_SRC_PORT_MAX) |
| 1141 | + *max = ntohs(f->cf_src_port_max); |
| 1142 | + else |
| 1143 | + *max = 0; |
| 1144 | + } |
| 1145 | + |
| 1146 | + return 0; |
| 1147 | +} |
| 1148 | + |
| 1149 | +int rtnl_flower_get_dst_port_range(struct rtnl_cls *cls, uint16_t *min, uint16_t *max) |
| 1150 | +{ |
| 1151 | + struct rtnl_flower *f = rtnl_tc_data_peek(TC_CAST(cls)); |
| 1152 | + |
| 1153 | + if (!f) |
| 1154 | + return -NLE_INVAL; |
| 1155 | + |
| 1156 | + if (min) { |
| 1157 | + if (f->cf_mask & FLOWER_ATTR_DST_PORT_MIN) |
| 1158 | + *min = ntohs(f->cf_dst_port_min); |
| 1159 | + else |
| 1160 | + *min = 0; |
| 1161 | + } |
| 1162 | + |
| 1163 | + if (max) { |
| 1164 | + if (f->cf_mask & FLOWER_ATTR_DST_PORT_MAX) |
| 1165 | + *max = ntohs(f->cf_dst_port_max); |
| 1166 | + else |
| 1167 | + *max = 0; |
| 1168 | + } |
| 1169 | + |
| 1170 | + return 0; |
| 1171 | +} |
| 1172 | + |
1048 | 1173 | /** @} */ |
1049 | 1174 |
|
1050 | 1175 | static struct rtnl_tc_ops flower_ops = { |
|
0 commit comments