| .. | .. |
|---|
| 189 | 189 | return true; |
|---|
| 190 | 190 | } |
|---|
| 191 | 191 | |
|---|
| 192 | +static inline int red_get_flags(unsigned char qopt_flags, |
|---|
| 193 | + unsigned char historic_mask, |
|---|
| 194 | + struct nlattr *flags_attr, |
|---|
| 195 | + unsigned char supported_mask, |
|---|
| 196 | + struct nla_bitfield32 *p_flags, |
|---|
| 197 | + unsigned char *p_userbits, |
|---|
| 198 | + struct netlink_ext_ack *extack) |
|---|
| 199 | +{ |
|---|
| 200 | + struct nla_bitfield32 flags; |
|---|
| 201 | + |
|---|
| 202 | + if (qopt_flags && flags_attr) { |
|---|
| 203 | + NL_SET_ERR_MSG_MOD(extack, "flags should be passed either through qopt, or through a dedicated attribute"); |
|---|
| 204 | + return -EINVAL; |
|---|
| 205 | + } |
|---|
| 206 | + |
|---|
| 207 | + if (flags_attr) { |
|---|
| 208 | + flags = nla_get_bitfield32(flags_attr); |
|---|
| 209 | + } else { |
|---|
| 210 | + flags.selector = historic_mask; |
|---|
| 211 | + flags.value = qopt_flags & historic_mask; |
|---|
| 212 | + } |
|---|
| 213 | + |
|---|
| 214 | + *p_flags = flags; |
|---|
| 215 | + *p_userbits = qopt_flags & ~historic_mask; |
|---|
| 216 | + return 0; |
|---|
| 217 | +} |
|---|
| 218 | + |
|---|
| 219 | +static inline int red_validate_flags(unsigned char flags, |
|---|
| 220 | + struct netlink_ext_ack *extack) |
|---|
| 221 | +{ |
|---|
| 222 | + if ((flags & TC_RED_NODROP) && !(flags & TC_RED_ECN)) { |
|---|
| 223 | + NL_SET_ERR_MSG_MOD(extack, "nodrop mode is only meaningful with ECN"); |
|---|
| 224 | + return -EINVAL; |
|---|
| 225 | + } |
|---|
| 226 | + |
|---|
| 227 | + return 0; |
|---|
| 228 | +} |
|---|
| 229 | + |
|---|
| 192 | 230 | static inline void red_set_parms(struct red_parms *p, |
|---|
| 193 | 231 | u32 qth_min, u32 qth_max, u8 Wlog, u8 Plog, |
|---|
| 194 | 232 | u8 Scell_log, u8 *stab, u32 max_P) |
|---|