^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2007-2017 Nicira, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "flow.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "datapath.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/if_ether.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/if_vlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <net/llc_pdu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/jhash.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/llc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/in.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/rcupdate.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/sctp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/udp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/icmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/icmpv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/rculist.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <net/geneve.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <net/ndisc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <net/mpls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <net/vxlan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <net/tun_proto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <net/erspan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "flow_netlink.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct ovs_len_tbl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const struct ovs_len_tbl *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define OVS_ATTR_NESTED -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define OVS_ATTR_VARIABLE -2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static bool actions_may_change_flow(const struct nlattr *actions)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) nla_for_each_nested(nla, actions, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u16 action = nla_type(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) switch (action) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) case OVS_ACTION_ATTR_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) case OVS_ACTION_ATTR_RECIRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case OVS_ACTION_ATTR_TRUNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) case OVS_ACTION_ATTR_USERSPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case OVS_ACTION_ATTR_CT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) case OVS_ACTION_ATTR_CT_CLEAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) case OVS_ACTION_ATTR_HASH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case OVS_ACTION_ATTR_POP_ETH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) case OVS_ACTION_ATTR_POP_MPLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) case OVS_ACTION_ATTR_POP_NSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case OVS_ACTION_ATTR_POP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) case OVS_ACTION_ATTR_PUSH_ETH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) case OVS_ACTION_ATTR_PUSH_MPLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case OVS_ACTION_ATTR_PUSH_NSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) case OVS_ACTION_ATTR_PUSH_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) case OVS_ACTION_ATTR_SAMPLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case OVS_ACTION_ATTR_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) case OVS_ACTION_ATTR_SET_MASKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) case OVS_ACTION_ATTR_METER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case OVS_ACTION_ATTR_CHECK_PKT_LEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) case OVS_ACTION_ATTR_ADD_MPLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) case OVS_ACTION_ATTR_DEC_TTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) static void update_range(struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) size_t offset, size_t size, bool is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct sw_flow_key_range *range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) size_t start = rounddown(offset, sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) size_t end = roundup(offset + size, sizeof(long));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (!is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) range = &match->range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) range = &match->mask->range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (range->start == range->end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) range->start = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) range->end = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (range->start > start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) range->start = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (range->end < end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) range->end = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define SW_FLOW_KEY_PUT(match, field, value, is_mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) update_range(match, offsetof(struct sw_flow_key, field), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) sizeof((match)->key->field), is_mask); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (is_mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) (match)->mask->key.field = value; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) (match)->key->field = value; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define SW_FLOW_KEY_MEMCPY_OFFSET(match, offset, value_p, len, is_mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) update_range(match, offset, len, is_mask); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (is_mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) memcpy((u8 *)&(match)->mask->key + offset, value_p, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) len); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) memcpy((u8 *)(match)->key + offset, value_p, len); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define SW_FLOW_KEY_MEMCPY(match, field, value_p, len, is_mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) SW_FLOW_KEY_MEMCPY_OFFSET(match, offsetof(struct sw_flow_key, field), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) value_p, len, is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define SW_FLOW_KEY_MEMSET_FIELD(match, field, value, is_mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) update_range(match, offsetof(struct sw_flow_key, field), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) sizeof((match)->key->field), is_mask); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (is_mask) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) memset((u8 *)&(match)->mask->key.field, value, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) sizeof((match)->mask->key.field)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) memset((u8 *)&(match)->key->field, value, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) sizeof((match)->key->field)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static bool match_validate(const struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) u64 key_attrs, u64 mask_attrs, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) u64 key_expected = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u64 mask_allowed = key_attrs; /* At most allow all key attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* The following mask attributes allowed only if they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * pass the validation tests. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) mask_allowed &= ~((1 << OVS_KEY_ATTR_IPV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) | (1 << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) | (1 << OVS_KEY_ATTR_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) | (1 << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) | (1 << OVS_KEY_ATTR_TCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) | (1 << OVS_KEY_ATTR_TCP_FLAGS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) | (1 << OVS_KEY_ATTR_UDP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) | (1 << OVS_KEY_ATTR_SCTP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) | (1 << OVS_KEY_ATTR_ICMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) | (1 << OVS_KEY_ATTR_ICMPV6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) | (1 << OVS_KEY_ATTR_ARP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) | (1 << OVS_KEY_ATTR_ND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) | (1 << OVS_KEY_ATTR_MPLS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) | (1 << OVS_KEY_ATTR_NSH));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) /* Always allowed mask fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) mask_allowed |= ((1 << OVS_KEY_ATTR_TUNNEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) | (1 << OVS_KEY_ATTR_IN_PORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) | (1 << OVS_KEY_ATTR_ETHERTYPE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Check key attributes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) if (match->key->eth.type == htons(ETH_P_ARP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) || match->key->eth.type == htons(ETH_P_RARP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) key_expected |= 1 << OVS_KEY_ATTR_ARP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (match->mask && (match->mask->key.eth.type == htons(0xffff)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mask_allowed |= 1 << OVS_KEY_ATTR_ARP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (eth_p_mpls(match->key->eth.type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) key_expected |= 1 << OVS_KEY_ATTR_MPLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (match->mask && (match->mask->key.eth.type == htons(0xffff)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) mask_allowed |= 1 << OVS_KEY_ATTR_MPLS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (match->key->eth.type == htons(ETH_P_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) key_expected |= 1 << OVS_KEY_ATTR_IPV4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (match->mask && match->mask->key.eth.type == htons(0xffff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) mask_allowed |= 1 << OVS_KEY_ATTR_IPV4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) mask_allowed |= 1 << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (match->key->ip.frag != OVS_FRAG_TYPE_LATER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (match->key->ip.proto == IPPROTO_UDP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) key_expected |= 1 << OVS_KEY_ATTR_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (match->mask && (match->mask->key.ip.proto == 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) mask_allowed |= 1 << OVS_KEY_ATTR_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (match->key->ip.proto == IPPROTO_SCTP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) key_expected |= 1 << OVS_KEY_ATTR_SCTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (match->mask && (match->mask->key.ip.proto == 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) mask_allowed |= 1 << OVS_KEY_ATTR_SCTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (match->key->ip.proto == IPPROTO_TCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) key_expected |= 1 << OVS_KEY_ATTR_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) key_expected |= 1 << OVS_KEY_ATTR_TCP_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (match->mask && (match->mask->key.ip.proto == 0xff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) mask_allowed |= 1 << OVS_KEY_ATTR_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) mask_allowed |= 1 << OVS_KEY_ATTR_TCP_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (match->key->ip.proto == IPPROTO_ICMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) key_expected |= 1 << OVS_KEY_ATTR_ICMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (match->mask && (match->mask->key.ip.proto == 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) mask_allowed |= 1 << OVS_KEY_ATTR_ICMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) if (match->key->eth.type == htons(ETH_P_IPV6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) key_expected |= 1 << OVS_KEY_ATTR_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (match->mask && match->mask->key.eth.type == htons(0xffff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) mask_allowed |= 1 << OVS_KEY_ATTR_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) mask_allowed |= 1 << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (match->key->ip.frag != OVS_FRAG_TYPE_LATER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (match->key->ip.proto == IPPROTO_UDP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) key_expected |= 1 << OVS_KEY_ATTR_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (match->mask && (match->mask->key.ip.proto == 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) mask_allowed |= 1 << OVS_KEY_ATTR_UDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (match->key->ip.proto == IPPROTO_SCTP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) key_expected |= 1 << OVS_KEY_ATTR_SCTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (match->mask && (match->mask->key.ip.proto == 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) mask_allowed |= 1 << OVS_KEY_ATTR_SCTP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (match->key->ip.proto == IPPROTO_TCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) key_expected |= 1 << OVS_KEY_ATTR_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) key_expected |= 1 << OVS_KEY_ATTR_TCP_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (match->mask && (match->mask->key.ip.proto == 0xff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mask_allowed |= 1 << OVS_KEY_ATTR_TCP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mask_allowed |= 1 << OVS_KEY_ATTR_TCP_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (match->key->ip.proto == IPPROTO_ICMPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) key_expected |= 1 << OVS_KEY_ATTR_ICMPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (match->mask && (match->mask->key.ip.proto == 0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) mask_allowed |= 1 << OVS_KEY_ATTR_ICMPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (match->key->tp.src ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) htons(NDISC_NEIGHBOUR_SOLICITATION) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) match->key->tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) key_expected |= 1 << OVS_KEY_ATTR_ND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* Original direction conntrack tuple
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * uses the same space as the ND fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * in the key, so both are not allowed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * at the same time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) mask_allowed &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (match->mask && (match->mask->key.tp.src == htons(0xff)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) mask_allowed |= 1 << OVS_KEY_ATTR_ND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (match->key->eth.type == htons(ETH_P_NSH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) key_expected |= 1 << OVS_KEY_ATTR_NSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (match->mask &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) match->mask->key.eth.type == htons(0xffff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mask_allowed |= 1 << OVS_KEY_ATTR_NSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if ((key_attrs & key_expected) != key_expected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Key attributes check failed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) OVS_NLERR(log, "Missing key (keys=%llx, expected=%llx)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) (unsigned long long)key_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) (unsigned long long)key_expected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if ((mask_attrs & mask_allowed) != mask_attrs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* Mask attributes check failed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) OVS_NLERR(log, "Unexpected mask (mask=%llx, allowed=%llx)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) (unsigned long long)mask_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) (unsigned long long)mask_allowed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) size_t ovs_tun_key_attr_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* Whenever adding new OVS_TUNNEL_KEY_ FIELDS, we should consider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * updating this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return nla_total_size_64bit(8) /* OVS_TUNNEL_KEY_ATTR_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) + nla_total_size(16) /* OVS_TUNNEL_KEY_ATTR_IPV[46]_SRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) + nla_total_size(16) /* OVS_TUNNEL_KEY_ATTR_IPV[46]_DST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) + nla_total_size(1) /* OVS_TUNNEL_KEY_ATTR_TTL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_CSUM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) + nla_total_size(0) /* OVS_TUNNEL_KEY_ATTR_OAM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) + nla_total_size(256) /* OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS is mutually exclusive with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS and covered by it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) + nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_SRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) + nla_total_size(2); /* OVS_TUNNEL_KEY_ATTR_TP_DST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static size_t ovs_nsh_key_attr_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /* Whenever adding new OVS_NSH_KEY_ FIELDS, we should consider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * updating this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return nla_total_size(NSH_BASE_HDR_LEN) /* OVS_NSH_KEY_ATTR_BASE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* OVS_NSH_KEY_ATTR_MD1 and OVS_NSH_KEY_ATTR_MD2 are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * mutually exclusive, so the bigger one can cover
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * the small one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) + nla_total_size(NSH_CTX_HDRS_MAX_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) size_t ovs_key_attr_size(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* Whenever adding new OVS_KEY_ FIELDS, we should consider
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) * updating this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) BUILD_BUG_ON(OVS_KEY_ATTR_TUNNEL_INFO != 29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return nla_total_size(4) /* OVS_KEY_ATTR_PRIORITY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) + nla_total_size(0) /* OVS_KEY_ATTR_TUNNEL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) + ovs_tun_key_attr_size()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) + nla_total_size(4) /* OVS_KEY_ATTR_IN_PORT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) + nla_total_size(4) /* OVS_KEY_ATTR_SKB_MARK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) + nla_total_size(4) /* OVS_KEY_ATTR_DP_HASH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) + nla_total_size(4) /* OVS_KEY_ATTR_RECIRC_ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) + nla_total_size(4) /* OVS_KEY_ATTR_CT_STATE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) + nla_total_size(2) /* OVS_KEY_ATTR_CT_ZONE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) + nla_total_size(4) /* OVS_KEY_ATTR_CT_MARK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) + nla_total_size(16) /* OVS_KEY_ATTR_CT_LABELS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) + nla_total_size(40) /* OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) + nla_total_size(0) /* OVS_KEY_ATTR_NSH */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) + ovs_nsh_key_attr_size()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) + nla_total_size(12) /* OVS_KEY_ATTR_ETHERNET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) + nla_total_size(4) /* OVS_KEY_ATTR_VLAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) + nla_total_size(0) /* OVS_KEY_ATTR_ENCAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) + nla_total_size(2) /* OVS_KEY_ATTR_ETHERTYPE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) + nla_total_size(40) /* OVS_KEY_ATTR_IPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) + nla_total_size(2) /* OVS_KEY_ATTR_ICMPV6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) + nla_total_size(28); /* OVS_KEY_ATTR_ND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static const struct ovs_len_tbl ovs_vxlan_ext_key_lens[OVS_VXLAN_EXT_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) [OVS_VXLAN_EXT_GBP] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) [OVS_TUNNEL_KEY_ATTR_ID] = { .len = sizeof(u64) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) [OVS_TUNNEL_KEY_ATTR_IPV4_SRC] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) [OVS_TUNNEL_KEY_ATTR_IPV4_DST] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) [OVS_TUNNEL_KEY_ATTR_TOS] = { .len = 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) [OVS_TUNNEL_KEY_ATTR_TTL] = { .len = 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) [OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT] = { .len = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) [OVS_TUNNEL_KEY_ATTR_CSUM] = { .len = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) [OVS_TUNNEL_KEY_ATTR_TP_SRC] = { .len = sizeof(u16) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) [OVS_TUNNEL_KEY_ATTR_TP_DST] = { .len = sizeof(u16) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) [OVS_TUNNEL_KEY_ATTR_OAM] = { .len = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) [OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS] = { .len = OVS_ATTR_VARIABLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) [OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS] = { .len = OVS_ATTR_NESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .next = ovs_vxlan_ext_key_lens },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = sizeof(struct in6_addr) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = OVS_ATTR_VARIABLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) [OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE] = { .len = 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static const struct ovs_len_tbl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ovs_nsh_key_attr_lens[OVS_NSH_KEY_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) [OVS_NSH_KEY_ATTR_BASE] = { .len = sizeof(struct ovs_nsh_key_base) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) [OVS_NSH_KEY_ATTR_MD1] = { .len = sizeof(struct ovs_nsh_key_md1) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) [OVS_NSH_KEY_ATTR_MD2] = { .len = OVS_ATTR_VARIABLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static const struct ovs_len_tbl ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) [OVS_KEY_ATTR_ENCAP] = { .len = OVS_ATTR_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) [OVS_KEY_ATTR_PRIORITY] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) [OVS_KEY_ATTR_IN_PORT] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) [OVS_KEY_ATTR_SKB_MARK] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) [OVS_KEY_ATTR_ETHERNET] = { .len = sizeof(struct ovs_key_ethernet) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) [OVS_KEY_ATTR_VLAN] = { .len = sizeof(__be16) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) [OVS_KEY_ATTR_ETHERTYPE] = { .len = sizeof(__be16) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) [OVS_KEY_ATTR_IPV4] = { .len = sizeof(struct ovs_key_ipv4) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) [OVS_KEY_ATTR_IPV6] = { .len = sizeof(struct ovs_key_ipv6) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) [OVS_KEY_ATTR_TCP] = { .len = sizeof(struct ovs_key_tcp) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) [OVS_KEY_ATTR_TCP_FLAGS] = { .len = sizeof(__be16) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) [OVS_KEY_ATTR_UDP] = { .len = sizeof(struct ovs_key_udp) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) [OVS_KEY_ATTR_SCTP] = { .len = sizeof(struct ovs_key_sctp) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) [OVS_KEY_ATTR_ICMP] = { .len = sizeof(struct ovs_key_icmp) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) [OVS_KEY_ATTR_ICMPV6] = { .len = sizeof(struct ovs_key_icmpv6) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) [OVS_KEY_ATTR_ARP] = { .len = sizeof(struct ovs_key_arp) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) [OVS_KEY_ATTR_ND] = { .len = sizeof(struct ovs_key_nd) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) [OVS_KEY_ATTR_RECIRC_ID] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) [OVS_KEY_ATTR_DP_HASH] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) [OVS_KEY_ATTR_TUNNEL] = { .len = OVS_ATTR_NESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) .next = ovs_tunnel_key_lens, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) [OVS_KEY_ATTR_MPLS] = { .len = OVS_ATTR_VARIABLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) [OVS_KEY_ATTR_CT_STATE] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) [OVS_KEY_ATTR_CT_ZONE] = { .len = sizeof(u16) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) [OVS_KEY_ATTR_CT_MARK] = { .len = sizeof(u32) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) [OVS_KEY_ATTR_CT_LABELS] = { .len = sizeof(struct ovs_key_ct_labels) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) .len = sizeof(struct ovs_key_ct_tuple_ipv4) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) [OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .len = sizeof(struct ovs_key_ct_tuple_ipv6) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) [OVS_KEY_ATTR_NSH] = { .len = OVS_ATTR_NESTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .next = ovs_nsh_key_attr_lens, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static bool check_attr_len(unsigned int attr_len, unsigned int expected_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) return expected_len == attr_len ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) expected_len == OVS_ATTR_NESTED ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) expected_len == OVS_ATTR_VARIABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static bool is_all_zero(const u8 *fp, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (!fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) for (i = 0; i < size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (fp[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int __parse_flow_nlattrs(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) const struct nlattr *a[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) u64 *attrsp, bool log, bool nz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) const struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) u64 attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) attrs = *attrsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) nla_for_each_nested(nla, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) u16 type = nla_type(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) int expected_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (type > OVS_KEY_ATTR_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) OVS_NLERR(log, "Key type %d is out of range max %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) type, OVS_KEY_ATTR_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (attrs & (1 << type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) OVS_NLERR(log, "Duplicate key (type %d).", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) expected_len = ovs_key_lens[type].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) if (!check_attr_len(nla_len(nla), expected_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) OVS_NLERR(log, "Key %d has unexpected len %d expected %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) type, nla_len(nla), expected_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (!nz || !is_all_zero(nla_data(nla), nla_len(nla))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) attrs |= 1 << type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) a[type] = nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) OVS_NLERR(log, "Message has %d unknown bytes.", rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) *attrsp = attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static int parse_flow_mask_nlattrs(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) const struct nlattr *a[], u64 *attrsp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return __parse_flow_nlattrs(attr, a, attrsp, log, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) int parse_flow_nlattrs(const struct nlattr *attr, const struct nlattr *a[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) u64 *attrsp, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return __parse_flow_nlattrs(attr, a, attrsp, log, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) static int genev_tun_opt_from_nlattr(const struct nlattr *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct sw_flow_match *match, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) unsigned long opt_key_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) if (nla_len(a) > sizeof(match->key->tun_opts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) OVS_NLERR(log, "Geneve option length err (len %d, max %zu).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) nla_len(a), sizeof(match->key->tun_opts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (nla_len(a) % 4 != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) OVS_NLERR(log, "Geneve opt len %d is not a multiple of 4.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) nla_len(a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /* We need to record the length of the options passed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * down, otherwise packets with the same format but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * additional options will be silently matched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) if (!is_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) SW_FLOW_KEY_PUT(match, tun_opts_len, nla_len(a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) /* This is somewhat unusual because it looks at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) * both the key and mask while parsing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * attributes (and by extension assumes the key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * is parsed first). Normally, we would verify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) * that each is the correct length and that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * attributes line up in the validate function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) * However, that is difficult because this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * variable length and we won't have the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) * information later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (match->key->tun_opts_len != nla_len(a)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) OVS_NLERR(log, "Geneve option len %d != mask len %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) match->key->tun_opts_len, nla_len(a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) opt_key_offset = TUN_METADATA_OFFSET(nla_len(a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) nla_len(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct sw_flow_match *match, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) unsigned long opt_key_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) struct vxlan_metadata opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) BUILD_BUG_ON(sizeof(opts) > sizeof(match->key->tun_opts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) memset(&opts, 0, sizeof(opts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) nla_for_each_nested(a, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (type > OVS_VXLAN_EXT_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) OVS_NLERR(log, "VXLAN extension %d out of range max %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) type, OVS_VXLAN_EXT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (!check_attr_len(nla_len(a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ovs_vxlan_ext_key_lens[type].len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) OVS_NLERR(log, "VXLAN extension %d has unexpected len %d expected %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) type, nla_len(a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ovs_vxlan_ext_key_lens[type].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) case OVS_VXLAN_EXT_GBP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) opts.gbp = nla_get_u32(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) OVS_NLERR(log, "Unknown VXLAN extension attribute %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) OVS_NLERR(log, "VXLAN extension message has %d unknown bytes.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) if (!is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) SW_FLOW_KEY_PUT(match, tun_opts_len, sizeof(opts), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) opt_key_offset = TUN_METADATA_OFFSET(sizeof(opts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, &opts, sizeof(opts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) static int erspan_tun_opt_from_nlattr(const struct nlattr *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct sw_flow_match *match, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) unsigned long opt_key_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) BUILD_BUG_ON(sizeof(struct erspan_metadata) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) sizeof(match->key->tun_opts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (nla_len(a) > sizeof(match->key->tun_opts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) OVS_NLERR(log, "ERSPAN option length err (len %d, max %zu).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) nla_len(a), sizeof(match->key->tun_opts));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (!is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) SW_FLOW_KEY_PUT(match, tun_opts_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) sizeof(struct erspan_metadata), false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) SW_FLOW_KEY_PUT(match, tun_opts_len, 0xff, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) opt_key_offset = TUN_METADATA_OFFSET(nla_len(a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, nla_data(a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) nla_len(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static int ip_tun_from_nlattr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct sw_flow_match *match, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) bool ttl = false, ipv4 = false, ipv6 = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) bool info_bridge_mode = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) __be16 tun_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) int opts_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) nla_for_each_nested(a, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (type > OVS_TUNNEL_KEY_ATTR_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) OVS_NLERR(log, "Tunnel attr %d out of range max %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) type, OVS_TUNNEL_KEY_ATTR_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (!check_attr_len(nla_len(a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) ovs_tunnel_key_lens[type].len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) OVS_NLERR(log, "Tunnel attr %d has unexpected len %d expected %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) type, nla_len(a), ovs_tunnel_key_lens[type].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) case OVS_TUNNEL_KEY_ATTR_ID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) SW_FLOW_KEY_PUT(match, tun_key.tun_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) nla_get_be64(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) tun_flags |= TUNNEL_KEY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) case OVS_TUNNEL_KEY_ATTR_IPV4_SRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) nla_get_in_addr(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) ipv4 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) case OVS_TUNNEL_KEY_ATTR_IPV4_DST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) SW_FLOW_KEY_PUT(match, tun_key.u.ipv4.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) nla_get_in_addr(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ipv4 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) case OVS_TUNNEL_KEY_ATTR_IPV6_SRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) nla_get_in6_addr(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ipv6 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) case OVS_TUNNEL_KEY_ATTR_IPV6_DST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) SW_FLOW_KEY_PUT(match, tun_key.u.ipv6.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) nla_get_in6_addr(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ipv6 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case OVS_TUNNEL_KEY_ATTR_TOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) SW_FLOW_KEY_PUT(match, tun_key.tos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) nla_get_u8(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) case OVS_TUNNEL_KEY_ATTR_TTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) SW_FLOW_KEY_PUT(match, tun_key.ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) nla_get_u8(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ttl = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) tun_flags |= TUNNEL_DONT_FRAGMENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) case OVS_TUNNEL_KEY_ATTR_CSUM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) tun_flags |= TUNNEL_CSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) case OVS_TUNNEL_KEY_ATTR_TP_SRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) SW_FLOW_KEY_PUT(match, tun_key.tp_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) nla_get_be16(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) case OVS_TUNNEL_KEY_ATTR_TP_DST:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) SW_FLOW_KEY_PUT(match, tun_key.tp_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) nla_get_be16(a), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) case OVS_TUNNEL_KEY_ATTR_OAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) tun_flags |= TUNNEL_OAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (opts_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) OVS_NLERR(log, "Multiple metadata blocks provided");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) err = genev_tun_opt_from_nlattr(a, match, is_mask, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) tun_flags |= TUNNEL_GENEVE_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) opts_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (opts_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) OVS_NLERR(log, "Multiple metadata blocks provided");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) err = vxlan_tun_opt_from_nlattr(a, match, is_mask, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) tun_flags |= TUNNEL_VXLAN_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) opts_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) case OVS_TUNNEL_KEY_ATTR_PAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (opts_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) OVS_NLERR(log, "Multiple metadata blocks provided");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) err = erspan_tun_opt_from_nlattr(a, match, is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) tun_flags |= TUNNEL_ERSPAN_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) opts_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) case OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) info_bridge_mode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) ipv4 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) OVS_NLERR(log, "Unknown IP tunnel attribute %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) SW_FLOW_KEY_PUT(match, tun_key.tun_flags, tun_flags, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) SW_FLOW_KEY_MEMSET_FIELD(match, tun_proto, 0xff, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) SW_FLOW_KEY_PUT(match, tun_proto, ipv6 ? AF_INET6 : AF_INET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (rem > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) OVS_NLERR(log, "IP tunnel attribute has %d unknown bytes.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (ipv4 && ipv6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) OVS_NLERR(log, "Mixed IPv4 and IPv6 tunnel attributes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!is_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (!ipv4 && !ipv6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) OVS_NLERR(log, "IP tunnel dst address not specified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (ipv4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (info_bridge_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (match->key->tun_key.u.ipv4.src ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) match->key->tun_key.u.ipv4.dst ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) match->key->tun_key.tp_src ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) match->key->tun_key.tp_dst ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) match->key->tun_key.ttl ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) match->key->tun_key.tos ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) tun_flags & ~TUNNEL_KEY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) OVS_NLERR(log, "IPv4 tun info is not correct");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) } else if (!match->key->tun_key.u.ipv4.dst) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) OVS_NLERR(log, "IPv4 tunnel dst address is zero");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (ipv6 && ipv6_addr_any(&match->key->tun_key.u.ipv6.dst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) OVS_NLERR(log, "IPv6 tunnel dst address is zero");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (!ttl && !info_bridge_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) OVS_NLERR(log, "IP tunnel TTL not specified.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return opts_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static int vxlan_opt_to_nlattr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) const void *tun_opts, int swkey_tun_opts_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) const struct vxlan_metadata *opts = tun_opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) nla = nla_nest_start_noflag(skb, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (nla_put_u32(skb, OVS_VXLAN_EXT_GBP, opts->gbp) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) nla_nest_end(skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) static int __ip_tun_to_nlattr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) const struct ip_tunnel_key *output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) const void *tun_opts, int swkey_tun_opts_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) unsigned short tun_proto, u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (output->tun_flags & TUNNEL_KEY &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) OVS_TUNNEL_KEY_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (mode & IP_TUNNEL_INFO_BRIDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) ? -EMSGSIZE : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) switch (tun_proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) case AF_INET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (output->u.ipv4.src &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) output->u.ipv4.src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (output->u.ipv4.dst &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) nla_put_in_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV4_DST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) output->u.ipv4.dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) case AF_INET6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (!ipv6_addr_any(&output->u.ipv6.src) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) nla_put_in6_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV6_SRC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) &output->u.ipv6.src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (!ipv6_addr_any(&output->u.ipv6.dst) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) nla_put_in6_addr(skb, OVS_TUNNEL_KEY_ATTR_IPV6_DST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) &output->u.ipv6.dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (output->tos &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TOS, output->tos))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (nla_put_u8(skb, OVS_TUNNEL_KEY_ATTR_TTL, output->ttl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) if ((output->tun_flags & TUNNEL_DONT_FRAGMENT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if ((output->tun_flags & TUNNEL_CSUM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_CSUM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (output->tp_src &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) nla_put_be16(skb, OVS_TUNNEL_KEY_ATTR_TP_SRC, output->tp_src))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (output->tp_dst &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) nla_put_be16(skb, OVS_TUNNEL_KEY_ATTR_TP_DST, output->tp_dst))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if ((output->tun_flags & TUNNEL_OAM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_OAM))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (swkey_tun_opts_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (output->tun_flags & TUNNEL_GENEVE_OPT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) nla_put(skb, OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) swkey_tun_opts_len, tun_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) else if (output->tun_flags & TUNNEL_VXLAN_OPT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) vxlan_opt_to_nlattr(skb, tun_opts, swkey_tun_opts_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) else if (output->tun_flags & TUNNEL_ERSPAN_OPT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) nla_put(skb, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) swkey_tun_opts_len, tun_opts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) static int ip_tun_to_nlattr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) const struct ip_tunnel_key *output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) const void *tun_opts, int swkey_tun_opts_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) unsigned short tun_proto, u8 mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) nla = nla_nest_start_noflag(skb, OVS_KEY_ATTR_TUNNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) err = __ip_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) tun_proto, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) nla_nest_end(skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) int ovs_nla_put_tunnel_info(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct ip_tunnel_info *tun_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return __ip_tun_to_nlattr(skb, &tun_info->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) ip_tunnel_info_opts(tun_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) tun_info->options_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) ip_tunnel_info_af(tun_info), tun_info->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) static int encode_vlan_from_nlattrs(struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) const struct nlattr *a[],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) bool is_mask, bool inner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) __be16 tci = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) __be16 tpid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (a[OVS_KEY_ATTR_VLAN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (a[OVS_KEY_ATTR_ETHERTYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) tpid = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (likely(!inner)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) SW_FLOW_KEY_PUT(match, eth.vlan.tpid, tpid, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) SW_FLOW_KEY_PUT(match, eth.vlan.tci, tci, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) SW_FLOW_KEY_PUT(match, eth.cvlan.tpid, tpid, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) SW_FLOW_KEY_PUT(match, eth.cvlan.tci, tci, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) static int validate_vlan_from_nlattrs(const struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) u64 key_attrs, bool inner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) const struct nlattr **a, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) __be16 tci = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (!((key_attrs & (1 << OVS_KEY_ATTR_ETHERNET)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) (key_attrs & (1 << OVS_KEY_ATTR_ETHERTYPE)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) eth_type_vlan(nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE])))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* Not a VLAN. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (!((key_attrs & (1 << OVS_KEY_ATTR_VLAN)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) (key_attrs & (1 << OVS_KEY_ATTR_ENCAP)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) OVS_NLERR(log, "Invalid %s frame", (inner) ? "C-VLAN" : "VLAN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (a[OVS_KEY_ATTR_VLAN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) if (!(tci & htons(VLAN_CFI_MASK))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (tci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) OVS_NLERR(log, "%s TCI does not have VLAN_CFI_MASK bit set.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) (inner) ? "C-VLAN" : "VLAN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) } else if (nla_len(a[OVS_KEY_ATTR_ENCAP])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) /* Corner case for truncated VLAN header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) OVS_NLERR(log, "Truncated %s header has non-zero encap attribute.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) (inner) ? "C-VLAN" : "VLAN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) static int validate_vlan_mask_from_nlattrs(const struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) u64 key_attrs, bool inner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) const struct nlattr **a, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) __be16 tci = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) __be16 tpid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) bool encap_valid = !!(match->key->eth.vlan.tci &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) htons(VLAN_CFI_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) bool i_encap_valid = !!(match->key->eth.cvlan.tci &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) htons(VLAN_CFI_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (!(key_attrs & (1 << OVS_KEY_ATTR_ENCAP))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) /* Not a VLAN. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if ((!inner && !encap_valid) || (inner && !i_encap_valid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) OVS_NLERR(log, "Encap mask attribute is set for non-%s frame.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) (inner) ? "C-VLAN" : "VLAN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (a[OVS_KEY_ATTR_VLAN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (a[OVS_KEY_ATTR_ETHERTYPE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) tpid = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (tpid != htons(0xffff)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) OVS_NLERR(log, "Must have an exact match on %s TPID (mask=%x).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) (inner) ? "C-VLAN" : "VLAN", ntohs(tpid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (!(tci & htons(VLAN_CFI_MASK))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) OVS_NLERR(log, "%s TCI mask does not have exact match for VLAN_CFI_MASK bit.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) (inner) ? "C-VLAN" : "VLAN");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) static int __parse_vlan_from_nlattrs(struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) u64 *key_attrs, bool inner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) const struct nlattr **a, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) const struct nlattr *encap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (!is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) err = validate_vlan_from_nlattrs(match, *key_attrs, inner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) a, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) err = validate_vlan_mask_from_nlattrs(match, *key_attrs, inner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) a, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (err <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) err = encode_vlan_from_nlattrs(match, a, is_mask, inner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) *key_attrs &= ~(1 << OVS_KEY_ATTR_ENCAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) *key_attrs &= ~(1 << OVS_KEY_ATTR_VLAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) *key_attrs &= ~(1 << OVS_KEY_ATTR_ETHERTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) encap = a[OVS_KEY_ATTR_ENCAP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if (!is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) err = parse_flow_nlattrs(encap, a, key_attrs, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) err = parse_flow_mask_nlattrs(encap, a, key_attrs, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static int parse_vlan_from_nlattrs(struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) u64 *key_attrs, const struct nlattr **a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) bool is_mask, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) bool encap_valid = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) err = __parse_vlan_from_nlattrs(match, key_attrs, false, a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) is_mask, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) encap_valid = !!(match->key->eth.vlan.tci & htons(VLAN_CFI_MASK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (encap_valid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) err = __parse_vlan_from_nlattrs(match, key_attrs, true, a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) is_mask, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static int parse_eth_type_from_nlattrs(struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) u64 *attrs, const struct nlattr **a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) bool is_mask, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) __be16 eth_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) eth_type = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (is_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /* Always exact match EtherType. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) eth_type = htons(0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) } else if (!eth_proto_is_802_3(eth_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) OVS_NLERR(log, "EtherType %x is less than min %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) ntohs(eth_type), ETH_P_802_3_MIN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) SW_FLOW_KEY_PUT(match, eth.type, eth_type, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) *attrs &= ~(1 << OVS_KEY_ATTR_ETHERTYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) static int metadata_from_nlattrs(struct net *net, struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) u64 *attrs, const struct nlattr **a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) bool is_mask, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) u8 mac_proto = MAC_PROTO_ETHERNET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (*attrs & (1 << OVS_KEY_ATTR_DP_HASH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) u32 hash_val = nla_get_u32(a[OVS_KEY_ATTR_DP_HASH]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) SW_FLOW_KEY_PUT(match, ovs_flow_hash, hash_val, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) *attrs &= ~(1 << OVS_KEY_ATTR_DP_HASH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (*attrs & (1 << OVS_KEY_ATTR_RECIRC_ID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) u32 recirc_id = nla_get_u32(a[OVS_KEY_ATTR_RECIRC_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) SW_FLOW_KEY_PUT(match, recirc_id, recirc_id, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) *attrs &= ~(1 << OVS_KEY_ATTR_RECIRC_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (*attrs & (1 << OVS_KEY_ATTR_PRIORITY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) SW_FLOW_KEY_PUT(match, phy.priority,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) nla_get_u32(a[OVS_KEY_ATTR_PRIORITY]), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) *attrs &= ~(1 << OVS_KEY_ATTR_PRIORITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (*attrs & (1 << OVS_KEY_ATTR_IN_PORT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) u32 in_port = nla_get_u32(a[OVS_KEY_ATTR_IN_PORT]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) if (is_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) in_port = 0xffffffff; /* Always exact match in_port. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) } else if (in_port >= DP_MAX_PORTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) OVS_NLERR(log, "Port %d exceeds max allowable %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) in_port, DP_MAX_PORTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) SW_FLOW_KEY_PUT(match, phy.in_port, in_port, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) *attrs &= ~(1 << OVS_KEY_ATTR_IN_PORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) } else if (!is_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) SW_FLOW_KEY_PUT(match, phy.in_port, DP_MAX_PORTS, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (*attrs & (1 << OVS_KEY_ATTR_SKB_MARK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) uint32_t mark = nla_get_u32(a[OVS_KEY_ATTR_SKB_MARK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) SW_FLOW_KEY_PUT(match, phy.skb_mark, mark, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) *attrs &= ~(1 << OVS_KEY_ATTR_SKB_MARK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (*attrs & (1 << OVS_KEY_ATTR_TUNNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (ip_tun_from_nlattr(a[OVS_KEY_ATTR_TUNNEL], match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) is_mask, log) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) *attrs &= ~(1 << OVS_KEY_ATTR_TUNNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (*attrs & (1 << OVS_KEY_ATTR_CT_STATE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) ovs_ct_verify(net, OVS_KEY_ATTR_CT_STATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) u32 ct_state = nla_get_u32(a[OVS_KEY_ATTR_CT_STATE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (ct_state & ~CT_SUPPORTED_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) OVS_NLERR(log, "ct_state flags %08x unsupported",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) ct_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) SW_FLOW_KEY_PUT(match, ct_state, ct_state, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (*attrs & (1 << OVS_KEY_ATTR_CT_ZONE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) ovs_ct_verify(net, OVS_KEY_ATTR_CT_ZONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) u16 ct_zone = nla_get_u16(a[OVS_KEY_ATTR_CT_ZONE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) SW_FLOW_KEY_PUT(match, ct_zone, ct_zone, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ZONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (*attrs & (1 << OVS_KEY_ATTR_CT_MARK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) ovs_ct_verify(net, OVS_KEY_ATTR_CT_MARK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) u32 mark = nla_get_u32(a[OVS_KEY_ATTR_CT_MARK]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) SW_FLOW_KEY_PUT(match, ct.mark, mark, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_MARK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) if (*attrs & (1 << OVS_KEY_ATTR_CT_LABELS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) ovs_ct_verify(net, OVS_KEY_ATTR_CT_LABELS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) const struct ovs_key_ct_labels *cl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) cl = nla_data(a[OVS_KEY_ATTR_CT_LABELS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) SW_FLOW_KEY_MEMCPY(match, ct.labels, cl->ct_labels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) sizeof(*cl), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_LABELS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) if (*attrs & (1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) const struct ovs_key_ct_tuple_ipv4 *ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ct = nla_data(a[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) SW_FLOW_KEY_PUT(match, ipv4.ct_orig.src, ct->ipv4_src, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) SW_FLOW_KEY_PUT(match, ipv4.ct_orig.dst, ct->ipv4_dst, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) SW_FLOW_KEY_PUT(match, ct_orig_proto, ct->ipv4_proto, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) if (*attrs & (1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) const struct ovs_key_ct_tuple_ipv6 *ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) ct = nla_data(a[OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) SW_FLOW_KEY_MEMCPY(match, ipv6.ct_orig.src, &ct->ipv6_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) sizeof(match->key->ipv6.ct_orig.src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) SW_FLOW_KEY_MEMCPY(match, ipv6.ct_orig.dst, &ct->ipv6_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) sizeof(match->key->ipv6.ct_orig.dst),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) SW_FLOW_KEY_PUT(match, ct.orig_tp.src, ct->src_port, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) SW_FLOW_KEY_PUT(match, ct.orig_tp.dst, ct->dst_port, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) SW_FLOW_KEY_PUT(match, ct_orig_proto, ct->ipv6_proto, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) *attrs &= ~(1ULL << OVS_KEY_ATTR_CT_ORIG_TUPLE_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) /* For layer 3 packets the Ethernet type is provided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * and treated as metadata but no MAC addresses are provided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (!(*attrs & (1ULL << OVS_KEY_ATTR_ETHERNET)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) (*attrs & (1ULL << OVS_KEY_ATTR_ETHERTYPE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) mac_proto = MAC_PROTO_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) /* Always exact match mac_proto */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) SW_FLOW_KEY_PUT(match, mac_proto, is_mask ? 0xff : mac_proto, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (mac_proto == MAC_PROTO_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) return parse_eth_type_from_nlattrs(match, attrs, a, is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) int nsh_hdr_from_nlattr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) struct nshhdr *nh, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) u8 flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) u8 ttl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) int mdlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) /* validate_nsh has check this, so we needn't do duplicate check here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (size < NSH_BASE_HDR_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) nla_for_each_nested(a, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) case OVS_NSH_KEY_ATTR_BASE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) const struct ovs_nsh_key_base *base = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) flags = base->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) ttl = base->ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) nh->np = base->np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) nh->mdtype = base->mdtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) nh->path_hdr = base->path_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) case OVS_NSH_KEY_ATTR_MD1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) mdlen = nla_len(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) if (mdlen > size - NSH_BASE_HDR_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) memcpy(&nh->md1, nla_data(a), mdlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) case OVS_NSH_KEY_ATTR_MD2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) mdlen = nla_len(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (mdlen > size - NSH_BASE_HDR_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) memcpy(&nh->md2, nla_data(a), mdlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) /* nsh header length = NSH_BASE_HDR_LEN + mdlen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) nh->ver_flags_ttl_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) nsh_set_flags_ttl_len(nh, flags, ttl, NSH_BASE_HDR_LEN + mdlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) int nsh_key_from_nlattr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) struct ovs_key_nsh *nsh, struct ovs_key_nsh *nsh_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /* validate_nsh has check this, so we needn't do duplicate check here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) nla_for_each_nested(a, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) case OVS_NSH_KEY_ATTR_BASE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) const struct ovs_nsh_key_base *base = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) const struct ovs_nsh_key_base *base_mask = base + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) nsh->base = *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) nsh_mask->base = *base_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) case OVS_NSH_KEY_ATTR_MD1: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) const struct ovs_nsh_key_md1 *md1 = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) const struct ovs_nsh_key_md1 *md1_mask = md1 + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) memcpy(nsh->context, md1->context, sizeof(*md1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) memcpy(nsh_mask->context, md1_mask->context,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) sizeof(*md1_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) case OVS_NSH_KEY_ATTR_MD2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) /* Not supported yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) static int nsh_key_put_from_nlattr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) struct sw_flow_match *match, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) bool is_push_nsh, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) bool has_base = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) bool has_md1 = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) bool has_md2 = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) u8 mdtype = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) int mdlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (WARN_ON(is_push_nsh && is_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) nla_for_each_nested(a, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (type > OVS_NSH_KEY_ATTR_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) OVS_NLERR(log, "nsh attr %d is out of range max %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) type, OVS_NSH_KEY_ATTR_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) if (!check_attr_len(nla_len(a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) ovs_nsh_key_attr_lens[type].len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) OVS_NLERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) "nsh attr %d has unexpected len %d expected %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) nla_len(a),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ovs_nsh_key_attr_lens[type].len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) case OVS_NSH_KEY_ATTR_BASE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) const struct ovs_nsh_key_base *base = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) has_base = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) mdtype = base->mdtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) SW_FLOW_KEY_PUT(match, nsh.base.flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) base->flags, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) SW_FLOW_KEY_PUT(match, nsh.base.ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) base->ttl, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) SW_FLOW_KEY_PUT(match, nsh.base.mdtype,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) base->mdtype, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) SW_FLOW_KEY_PUT(match, nsh.base.np,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) base->np, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) SW_FLOW_KEY_PUT(match, nsh.base.path_hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) base->path_hdr, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) case OVS_NSH_KEY_ATTR_MD1: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) const struct ovs_nsh_key_md1 *md1 = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) has_md1 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) for (i = 0; i < NSH_MD1_CONTEXT_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) SW_FLOW_KEY_PUT(match, nsh.context[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) md1->context[i], is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) case OVS_NSH_KEY_ATTR_MD2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (!is_push_nsh) /* Not supported MD type 2 yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) has_md2 = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) mdlen = nla_len(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (mdlen > NSH_CTX_HDRS_MAX_LEN || mdlen <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) OVS_NLERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) "Invalid MD length %d for MD type %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) mdlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) mdtype
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) OVS_NLERR(log, "Unknown nsh attribute %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (rem > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) OVS_NLERR(log, "nsh attribute has %d unknown bytes.", rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (has_md1 && has_md2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) OVS_NLERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) "invalid nsh attribute: md1 and md2 are exclusive."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (!is_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) if ((has_md1 && mdtype != NSH_M_TYPE1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) (has_md2 && mdtype != NSH_M_TYPE2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) OVS_NLERR(1, "nsh attribute has unmatched MD type %d.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) mdtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) if (is_push_nsh &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) (!has_base || (!has_md1 && !has_md2))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) OVS_NLERR(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) "push_nsh: missing base or metadata attributes"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) static int ovs_key_from_nlattrs(struct net *net, struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) u64 attrs, const struct nlattr **a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) bool is_mask, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) err = metadata_from_nlattrs(net, match, &attrs, a, is_mask, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) if (attrs & (1 << OVS_KEY_ATTR_ETHERNET)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) const struct ovs_key_ethernet *eth_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) eth_key = nla_data(a[OVS_KEY_ATTR_ETHERNET]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) SW_FLOW_KEY_MEMCPY(match, eth.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) eth_key->eth_src, ETH_ALEN, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) SW_FLOW_KEY_MEMCPY(match, eth.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) eth_key->eth_dst, ETH_ALEN, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) attrs &= ~(1 << OVS_KEY_ATTR_ETHERNET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) if (attrs & (1 << OVS_KEY_ATTR_VLAN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) /* VLAN attribute is always parsed before getting here since it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) * may occur multiple times.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) OVS_NLERR(log, "VLAN attribute unexpected.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (attrs & (1 << OVS_KEY_ATTR_ETHERTYPE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) err = parse_eth_type_from_nlattrs(match, &attrs, a, is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) } else if (!is_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) SW_FLOW_KEY_PUT(match, eth.type, htons(ETH_P_802_2), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) } else if (!match->key->eth.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) OVS_NLERR(log, "Either Ethernet header or EtherType is required.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (attrs & (1 << OVS_KEY_ATTR_IPV4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) const struct ovs_key_ipv4 *ipv4_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) ipv4_key = nla_data(a[OVS_KEY_ATTR_IPV4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (!is_mask && ipv4_key->ipv4_frag > OVS_FRAG_TYPE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) OVS_NLERR(log, "IPv4 frag type %d is out of range max %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) ipv4_key->ipv4_frag, OVS_FRAG_TYPE_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) SW_FLOW_KEY_PUT(match, ip.proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) ipv4_key->ipv4_proto, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) SW_FLOW_KEY_PUT(match, ip.tos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) ipv4_key->ipv4_tos, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) SW_FLOW_KEY_PUT(match, ip.ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) ipv4_key->ipv4_ttl, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) SW_FLOW_KEY_PUT(match, ip.frag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) ipv4_key->ipv4_frag, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) SW_FLOW_KEY_PUT(match, ipv4.addr.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) ipv4_key->ipv4_src, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) SW_FLOW_KEY_PUT(match, ipv4.addr.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) ipv4_key->ipv4_dst, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) attrs &= ~(1 << OVS_KEY_ATTR_IPV4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) if (attrs & (1 << OVS_KEY_ATTR_IPV6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) const struct ovs_key_ipv6 *ipv6_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) ipv6_key = nla_data(a[OVS_KEY_ATTR_IPV6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (!is_mask && ipv6_key->ipv6_frag > OVS_FRAG_TYPE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) OVS_NLERR(log, "IPv6 frag type %d is out of range max %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) if (!is_mask && ipv6_key->ipv6_label & htonl(0xFFF00000)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) OVS_NLERR(log, "IPv6 flow label %x is out of range (max=%x)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) ntohl(ipv6_key->ipv6_label), (1 << 20) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) SW_FLOW_KEY_PUT(match, ipv6.label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) ipv6_key->ipv6_label, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) SW_FLOW_KEY_PUT(match, ip.proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) ipv6_key->ipv6_proto, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) SW_FLOW_KEY_PUT(match, ip.tos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) ipv6_key->ipv6_tclass, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) SW_FLOW_KEY_PUT(match, ip.ttl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) ipv6_key->ipv6_hlimit, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) SW_FLOW_KEY_PUT(match, ip.frag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) ipv6_key->ipv6_frag, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) SW_FLOW_KEY_MEMCPY(match, ipv6.addr.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) ipv6_key->ipv6_src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) sizeof(match->key->ipv6.addr.src),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) SW_FLOW_KEY_MEMCPY(match, ipv6.addr.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) ipv6_key->ipv6_dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) sizeof(match->key->ipv6.addr.dst),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) attrs &= ~(1 << OVS_KEY_ATTR_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) if (attrs & (1 << OVS_KEY_ATTR_ARP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) const struct ovs_key_arp *arp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) arp_key = nla_data(a[OVS_KEY_ATTR_ARP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (!is_mask && (arp_key->arp_op & htons(0xff00))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) OVS_NLERR(log, "Unknown ARP opcode (opcode=%d).",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) arp_key->arp_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) SW_FLOW_KEY_PUT(match, ipv4.addr.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) arp_key->arp_sip, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) SW_FLOW_KEY_PUT(match, ipv4.addr.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) arp_key->arp_tip, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) SW_FLOW_KEY_PUT(match, ip.proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) ntohs(arp_key->arp_op), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) SW_FLOW_KEY_MEMCPY(match, ipv4.arp.sha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) arp_key->arp_sha, ETH_ALEN, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) SW_FLOW_KEY_MEMCPY(match, ipv4.arp.tha,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) arp_key->arp_tha, ETH_ALEN, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) attrs &= ~(1 << OVS_KEY_ATTR_ARP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) if (attrs & (1 << OVS_KEY_ATTR_NSH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (nsh_key_put_from_nlattr(a[OVS_KEY_ATTR_NSH], match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) is_mask, false, log) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) attrs &= ~(1 << OVS_KEY_ATTR_NSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (attrs & (1 << OVS_KEY_ATTR_MPLS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) const struct ovs_key_mpls *mpls_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) u32 hdr_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) u32 label_count, label_count_mask, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) mpls_key = nla_data(a[OVS_KEY_ATTR_MPLS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) hdr_len = nla_len(a[OVS_KEY_ATTR_MPLS]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) label_count = hdr_len / sizeof(struct ovs_key_mpls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) if (label_count == 0 || label_count > MPLS_LABEL_DEPTH ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) hdr_len % sizeof(struct ovs_key_mpls))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) label_count_mask = GENMASK(label_count - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) for (i = 0 ; i < label_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) SW_FLOW_KEY_PUT(match, mpls.lse[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) mpls_key[i].mpls_lse, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) SW_FLOW_KEY_PUT(match, mpls.num_labels_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) label_count_mask, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) attrs &= ~(1 << OVS_KEY_ATTR_MPLS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) if (attrs & (1 << OVS_KEY_ATTR_TCP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) const struct ovs_key_tcp *tcp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) tcp_key = nla_data(a[OVS_KEY_ATTR_TCP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) SW_FLOW_KEY_PUT(match, tp.src, tcp_key->tcp_src, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) SW_FLOW_KEY_PUT(match, tp.dst, tcp_key->tcp_dst, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) attrs &= ~(1 << OVS_KEY_ATTR_TCP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) if (attrs & (1 << OVS_KEY_ATTR_TCP_FLAGS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) SW_FLOW_KEY_PUT(match, tp.flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) nla_get_be16(a[OVS_KEY_ATTR_TCP_FLAGS]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) attrs &= ~(1 << OVS_KEY_ATTR_TCP_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (attrs & (1 << OVS_KEY_ATTR_UDP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) const struct ovs_key_udp *udp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) udp_key = nla_data(a[OVS_KEY_ATTR_UDP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) SW_FLOW_KEY_PUT(match, tp.src, udp_key->udp_src, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) SW_FLOW_KEY_PUT(match, tp.dst, udp_key->udp_dst, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) attrs &= ~(1 << OVS_KEY_ATTR_UDP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) if (attrs & (1 << OVS_KEY_ATTR_SCTP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) const struct ovs_key_sctp *sctp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) sctp_key = nla_data(a[OVS_KEY_ATTR_SCTP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) SW_FLOW_KEY_PUT(match, tp.src, sctp_key->sctp_src, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) SW_FLOW_KEY_PUT(match, tp.dst, sctp_key->sctp_dst, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) attrs &= ~(1 << OVS_KEY_ATTR_SCTP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) if (attrs & (1 << OVS_KEY_ATTR_ICMP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) const struct ovs_key_icmp *icmp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) icmp_key = nla_data(a[OVS_KEY_ATTR_ICMP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) SW_FLOW_KEY_PUT(match, tp.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) htons(icmp_key->icmp_type), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) SW_FLOW_KEY_PUT(match, tp.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) htons(icmp_key->icmp_code), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) attrs &= ~(1 << OVS_KEY_ATTR_ICMP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if (attrs & (1 << OVS_KEY_ATTR_ICMPV6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) const struct ovs_key_icmpv6 *icmpv6_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) icmpv6_key = nla_data(a[OVS_KEY_ATTR_ICMPV6]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) SW_FLOW_KEY_PUT(match, tp.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) htons(icmpv6_key->icmpv6_type), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) SW_FLOW_KEY_PUT(match, tp.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) htons(icmpv6_key->icmpv6_code), is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) attrs &= ~(1 << OVS_KEY_ATTR_ICMPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (attrs & (1 << OVS_KEY_ATTR_ND)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) const struct ovs_key_nd *nd_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) nd_key = nla_data(a[OVS_KEY_ATTR_ND]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) SW_FLOW_KEY_MEMCPY(match, ipv6.nd.target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) nd_key->nd_target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) sizeof(match->key->ipv6.nd.target),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) SW_FLOW_KEY_MEMCPY(match, ipv6.nd.sll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) nd_key->nd_sll, ETH_ALEN, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) SW_FLOW_KEY_MEMCPY(match, ipv6.nd.tll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) nd_key->nd_tll, ETH_ALEN, is_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) attrs &= ~(1 << OVS_KEY_ATTR_ND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (attrs != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) OVS_NLERR(log, "Unknown key attributes %llx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) (unsigned long long)attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) static void nlattr_set(struct nlattr *attr, u8 val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) const struct ovs_len_tbl *tbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) /* The nlattr stream should already have been validated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) nla_for_each_nested(nla, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (tbl[nla_type(nla)].len == OVS_ATTR_NESTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) nlattr_set(nla, val, tbl[nla_type(nla)].next ? : tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) memset(nla_data(nla), val, nla_len(nla));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) if (nla_type(nla) == OVS_KEY_ATTR_CT_STATE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) *(u32 *)nla_data(nla) &= CT_SUPPORTED_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) static void mask_set_nlattr(struct nlattr *attr, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) nlattr_set(attr, val, ovs_key_lens);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) * ovs_nla_get_match - parses Netlink attributes into a flow key and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) * mask. In case the 'mask' is NULL, the flow is treated as exact match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) * flow. Otherwise, it is treated as a wildcarded flow, except the mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) * does not include any don't care bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) * @net: Used to determine per-namespace field support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) * @match: receives the extracted flow match information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) * @nla_key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) * sequence. The fields should of the packet that triggered the creation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) * of this flow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) * @nla_mask: Optional. Netlink attribute holding nested %OVS_KEY_ATTR_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) * Netlink attribute specifies the mask field of the wildcarded flow.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) * @log: Boolean to allow kernel error logging. Normally true, but when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) * probing for feature compatibility this should be passed in as false to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) * suppress unnecessary error logging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) int ovs_nla_get_match(struct net *net, struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) const struct nlattr *nla_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) const struct nlattr *nla_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) const struct nlattr *a[OVS_KEY_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) struct nlattr *newmask = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) u64 key_attrs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) u64 mask_attrs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) err = parse_flow_nlattrs(nla_key, a, &key_attrs, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) err = parse_vlan_from_nlattrs(match, &key_attrs, a, false, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) err = ovs_key_from_nlattrs(net, match, key_attrs, a, false, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) if (match->mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) if (!nla_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) /* Create an exact match mask. We need to set to 0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) * all the 'match->mask' fields that have been touched
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) * in 'match->key'. We cannot simply memset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) * 'match->mask', because padding bytes and fields not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) * specified in 'match->key' should be left to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) * Instead, we use a stream of netlink attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) * copied from 'key' and set to 0xff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) * ovs_key_from_nlattrs() will take care of filling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) * 'match->mask' appropriately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) newmask = kmemdup(nla_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) nla_total_size(nla_len(nla_key)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (!newmask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) mask_set_nlattr(newmask, 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) /* The userspace does not send tunnel attributes that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) * are 0, but we should not wildcard them nonetheless.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (match->key->tun_proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) SW_FLOW_KEY_MEMSET_FIELD(match, tun_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 0xff, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) nla_mask = newmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) err = parse_flow_mask_nlattrs(nla_mask, a, &mask_attrs, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) goto free_newmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) /* Always match on tci. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) SW_FLOW_KEY_PUT(match, eth.vlan.tci, htons(0xffff), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) SW_FLOW_KEY_PUT(match, eth.cvlan.tci, htons(0xffff), true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) err = parse_vlan_from_nlattrs(match, &mask_attrs, a, true, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) goto free_newmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) err = ovs_key_from_nlattrs(net, match, mask_attrs, a, true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) goto free_newmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) if (!match_validate(match, key_attrs, mask_attrs, log))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) free_newmask:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) kfree(newmask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) static size_t get_ufid_len(const struct nlattr *attr, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) if (!attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) len = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (len < 1 || len > MAX_UFID_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) OVS_NLERR(log, "ufid size %u bytes exceeds the range (1, %d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) nla_len(attr), MAX_UFID_LENGTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) /* Initializes 'flow->ufid', returning true if 'attr' contains a valid UFID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) * or false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) bool ovs_nla_get_ufid(struct sw_flow_id *sfid, const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) sfid->ufid_len = get_ufid_len(attr, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (sfid->ufid_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) memcpy(sfid->ufid, nla_data(attr), sfid->ufid_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) return sfid->ufid_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) int ovs_nla_get_identifier(struct sw_flow_id *sfid, const struct nlattr *ufid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) const struct sw_flow_key *key, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) struct sw_flow_key *new_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) if (ovs_nla_get_ufid(sfid, ufid, log))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) /* If UFID was not provided, use unmasked key. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) new_key = kmalloc(sizeof(*new_key), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (!new_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) memcpy(new_key, key, sizeof(*key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) sfid->unmasked_key = new_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) u32 ovs_nla_get_ufid_flags(const struct nlattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) return attr ? nla_get_u32(attr) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) * ovs_nla_get_flow_metadata - parses Netlink attributes into a flow key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) * @net: Network namespace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) * @key: Receives extracted in_port, priority, tun_key, skb_mark and conntrack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) * metadata.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) * @a: Array of netlink attributes holding parsed %OVS_KEY_ATTR_* Netlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) * attributes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) * @attrs: Bit mask for the netlink attributes included in @a.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) * @log: Boolean to allow kernel error logging. Normally true, but when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) * probing for feature compatibility this should be passed in as false to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * suppress unnecessary error logging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) * This parses a series of Netlink attributes that form a flow key, which must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) * take the same form accepted by flow_from_nlattrs(), but only enough of it to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) * get the metadata, that is, the parts of the flow key that cannot be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) * extracted from the packet itself.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) * This must be called before the packet key fields are filled in 'key'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) int ovs_nla_get_flow_metadata(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) const struct nlattr *a[OVS_KEY_ATTR_MAX + 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) u64 attrs, struct sw_flow_key *key, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) struct sw_flow_match match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) memset(&match, 0, sizeof(match));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) match.key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) key->ct_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) key->ct_zone = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) key->ct_orig_proto = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) memset(&key->ct, 0, sizeof(key->ct));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) memset(&key->ipv4.ct_orig, 0, sizeof(key->ipv4.ct_orig));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) memset(&key->ipv6.ct_orig, 0, sizeof(key->ipv6.ct_orig));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) key->phy.in_port = DP_MAX_PORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) return metadata_from_nlattrs(net, &match, &attrs, a, false, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) static int ovs_nla_put_vlan(struct sk_buff *skb, const struct vlan_head *vh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) bool is_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) __be16 eth_type = !is_mask ? vh->tpid : htons(0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, eth_type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) nla_put_be16(skb, OVS_KEY_ATTR_VLAN, vh->tci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) static int nsh_key_to_nlattr(const struct ovs_key_nsh *nsh, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) struct nlattr *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) start = nla_nest_start_noflag(skb, OVS_KEY_ATTR_NSH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) if (!start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) if (nla_put(skb, OVS_NSH_KEY_ATTR_BASE, sizeof(nsh->base), &nsh->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) if (is_mask || nsh->base.mdtype == NSH_M_TYPE1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) if (nla_put(skb, OVS_NSH_KEY_ATTR_MD1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) sizeof(nsh->context), nsh->context))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) /* Don't support MD type 2 yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) nla_nest_end(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) const struct sw_flow_key *output, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) struct ovs_key_ethernet *eth_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) struct nlattr *encap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) struct nlattr *in_encap = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) if (nla_put_u32(skb, OVS_KEY_ATTR_RECIRC_ID, output->recirc_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) if (nla_put_u32(skb, OVS_KEY_ATTR_DP_HASH, output->ovs_flow_hash))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) if ((swkey->tun_proto || is_mask)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) const void *opts = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) if (output->tun_key.tun_flags & TUNNEL_OPTIONS_PRESENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (ip_tun_to_nlattr(skb, &output->tun_key, opts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) swkey->tun_opts_len, swkey->tun_proto, 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) if (swkey->phy.in_port == DP_MAX_PORTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) if (is_mask && (output->phy.in_port == 0xffff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) if (nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, 0xffffffff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) u16 upper_u16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) upper_u16 = !is_mask ? 0 : 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) if (nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) (upper_u16 << 16) | output->phy.in_port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) if (nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, output->phy.skb_mark))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (ovs_ct_put_key(swkey, output, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) if (ovs_key_mac_proto(swkey) == MAC_PROTO_ETHERNET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) eth_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) ether_addr_copy(eth_key->eth_src, output->eth.src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) ether_addr_copy(eth_key->eth_dst, output->eth.dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) if (swkey->eth.vlan.tci || eth_type_vlan(swkey->eth.type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) if (ovs_nla_put_vlan(skb, &output->eth.vlan, is_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) encap = nla_nest_start_noflag(skb, OVS_KEY_ATTR_ENCAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) if (!swkey->eth.vlan.tci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) goto unencap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) if (swkey->eth.cvlan.tci || eth_type_vlan(swkey->eth.type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) if (ovs_nla_put_vlan(skb, &output->eth.cvlan, is_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) in_encap = nla_nest_start_noflag(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) OVS_KEY_ATTR_ENCAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) if (!swkey->eth.cvlan.tci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) goto unencap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (swkey->eth.type == htons(ETH_P_802_2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) * Ethertype 802.2 is represented in the netlink with omitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) * OVS_KEY_ATTR_ETHERTYPE in the flow key attribute, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) * 0xffff in the mask attribute. Ethertype can also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) * be wildcarded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) if (is_mask && output->eth.type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) output->eth.type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) goto unencap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, output->eth.type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) if (eth_type_vlan(swkey->eth.type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) /* There are 3 VLAN tags, we don't know anything about the rest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) * of the packet, so truncate here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) WARN_ON_ONCE(!(encap && in_encap));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) goto unencap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) if (swkey->eth.type == htons(ETH_P_IP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) struct ovs_key_ipv4 *ipv4_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) nla = nla_reserve(skb, OVS_KEY_ATTR_IPV4, sizeof(*ipv4_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) ipv4_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) ipv4_key->ipv4_src = output->ipv4.addr.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) ipv4_key->ipv4_dst = output->ipv4.addr.dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) ipv4_key->ipv4_proto = output->ip.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) ipv4_key->ipv4_tos = output->ip.tos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) ipv4_key->ipv4_ttl = output->ip.ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) ipv4_key->ipv4_frag = output->ip.frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) } else if (swkey->eth.type == htons(ETH_P_IPV6)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) struct ovs_key_ipv6 *ipv6_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) nla = nla_reserve(skb, OVS_KEY_ATTR_IPV6, sizeof(*ipv6_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) ipv6_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) memcpy(ipv6_key->ipv6_src, &output->ipv6.addr.src,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) sizeof(ipv6_key->ipv6_src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) memcpy(ipv6_key->ipv6_dst, &output->ipv6.addr.dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) sizeof(ipv6_key->ipv6_dst));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) ipv6_key->ipv6_label = output->ipv6.label;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) ipv6_key->ipv6_proto = output->ip.proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) ipv6_key->ipv6_tclass = output->ip.tos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) ipv6_key->ipv6_hlimit = output->ip.ttl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) ipv6_key->ipv6_frag = output->ip.frag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) } else if (swkey->eth.type == htons(ETH_P_NSH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) if (nsh_key_to_nlattr(&output->nsh, is_mask, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) } else if (swkey->eth.type == htons(ETH_P_ARP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) swkey->eth.type == htons(ETH_P_RARP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) struct ovs_key_arp *arp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) nla = nla_reserve(skb, OVS_KEY_ATTR_ARP, sizeof(*arp_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) arp_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) memset(arp_key, 0, sizeof(struct ovs_key_arp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) arp_key->arp_sip = output->ipv4.addr.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) arp_key->arp_tip = output->ipv4.addr.dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) arp_key->arp_op = htons(output->ip.proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) ether_addr_copy(arp_key->arp_sha, output->ipv4.arp.sha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) ether_addr_copy(arp_key->arp_tha, output->ipv4.arp.tha);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) } else if (eth_p_mpls(swkey->eth.type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) u8 i, num_labels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) struct ovs_key_mpls *mpls_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) num_labels = hweight_long(output->mpls.num_labels_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) nla = nla_reserve(skb, OVS_KEY_ATTR_MPLS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) num_labels * sizeof(*mpls_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) mpls_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) for (i = 0; i < num_labels; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) mpls_key[i].mpls_lse = output->mpls.lse[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) if ((swkey->eth.type == htons(ETH_P_IP) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) swkey->eth.type == htons(ETH_P_IPV6)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) swkey->ip.frag != OVS_FRAG_TYPE_LATER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) if (swkey->ip.proto == IPPROTO_TCP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) struct ovs_key_tcp *tcp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) nla = nla_reserve(skb, OVS_KEY_ATTR_TCP, sizeof(*tcp_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) tcp_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) tcp_key->tcp_src = output->tp.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) tcp_key->tcp_dst = output->tp.dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) if (nla_put_be16(skb, OVS_KEY_ATTR_TCP_FLAGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) output->tp.flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) } else if (swkey->ip.proto == IPPROTO_UDP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) struct ovs_key_udp *udp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) nla = nla_reserve(skb, OVS_KEY_ATTR_UDP, sizeof(*udp_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) udp_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) udp_key->udp_src = output->tp.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) udp_key->udp_dst = output->tp.dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) } else if (swkey->ip.proto == IPPROTO_SCTP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) struct ovs_key_sctp *sctp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) nla = nla_reserve(skb, OVS_KEY_ATTR_SCTP, sizeof(*sctp_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) sctp_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) sctp_key->sctp_src = output->tp.src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) sctp_key->sctp_dst = output->tp.dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) } else if (swkey->eth.type == htons(ETH_P_IP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) swkey->ip.proto == IPPROTO_ICMP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) struct ovs_key_icmp *icmp_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) nla = nla_reserve(skb, OVS_KEY_ATTR_ICMP, sizeof(*icmp_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) icmp_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) icmp_key->icmp_type = ntohs(output->tp.src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) icmp_key->icmp_code = ntohs(output->tp.dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) } else if (swkey->eth.type == htons(ETH_P_IPV6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) swkey->ip.proto == IPPROTO_ICMPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) struct ovs_key_icmpv6 *icmpv6_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) nla = nla_reserve(skb, OVS_KEY_ATTR_ICMPV6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) sizeof(*icmpv6_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) icmpv6_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) icmpv6_key->icmpv6_type = ntohs(output->tp.src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) icmpv6_key->icmpv6_code = ntohs(output->tp.dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) if (swkey->tp.src == htons(NDISC_NEIGHBOUR_SOLICITATION) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) swkey->tp.src == htons(NDISC_NEIGHBOUR_ADVERTISEMENT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) struct ovs_key_nd *nd_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) nla = nla_reserve(skb, OVS_KEY_ATTR_ND, sizeof(*nd_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) nd_key = nla_data(nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) memcpy(nd_key->nd_target, &output->ipv6.nd.target,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) sizeof(nd_key->nd_target));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) ether_addr_copy(nd_key->nd_sll, output->ipv6.nd.sll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) ether_addr_copy(nd_key->nd_tll, output->ipv6.nd.tll);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) unencap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) if (in_encap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) nla_nest_end(skb, in_encap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) if (encap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) nla_nest_end(skb, encap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) int ovs_nla_put_key(const struct sw_flow_key *swkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) const struct sw_flow_key *output, int attr, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) nla = nla_nest_start_noflag(skb, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) err = __ovs_nla_put_key(swkey, output, is_mask, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) nla_nest_end(skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) int ovs_nla_put_identifier(const struct sw_flow *flow, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) if (ovs_identifier_is_ufid(&flow->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) return nla_put(skb, OVS_FLOW_ATTR_UFID, flow->id.ufid_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) flow->id.ufid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) return ovs_nla_put_key(flow->id.unmasked_key, flow->id.unmasked_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) OVS_FLOW_ATTR_KEY, false, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) int ovs_nla_put_masked_key(const struct sw_flow *flow, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) return ovs_nla_put_key(&flow->key, &flow->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) OVS_FLOW_ATTR_KEY, false, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) /* Called with ovs_mutex or RCU read lock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) int ovs_nla_put_mask(const struct sw_flow *flow, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) return ovs_nla_put_key(&flow->key, &flow->mask->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) OVS_FLOW_ATTR_MASK, true, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) #define MAX_ACTIONS_BUFSIZE (32 * 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) static struct sw_flow_actions *nla_alloc_flow_actions(int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) struct sw_flow_actions *sfa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) WARN_ON_ONCE(size > MAX_ACTIONS_BUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) sfa = kmalloc(sizeof(*sfa) + size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) if (!sfa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) sfa->actions_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) return sfa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) static void ovs_nla_free_set_action(const struct nlattr *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) const struct nlattr *ovs_key = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) struct ovs_tunnel_info *ovs_tun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) switch (nla_type(ovs_key)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) case OVS_KEY_ATTR_TUNNEL_INFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) ovs_tun = nla_data(ovs_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) dst_release((struct dst_entry *)ovs_tun->tun_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) void ovs_nla_free_flow_actions(struct sw_flow_actions *sf_acts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) const struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) int rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (!sf_acts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) nla_for_each_attr(a, sf_acts->actions, sf_acts->actions_len, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) switch (nla_type(a)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) case OVS_ACTION_ATTR_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) ovs_nla_free_set_action(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) case OVS_ACTION_ATTR_CT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) ovs_ct_free_action(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) kfree(sf_acts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) static void __ovs_nla_free_flow_actions(struct rcu_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) ovs_nla_free_flow_actions(container_of(head, struct sw_flow_actions, rcu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) /* Schedules 'sf_acts' to be freed after the next RCU grace period.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) * The caller must hold rcu_read_lock for this to be sensible. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) void ovs_nla_free_flow_actions_rcu(struct sw_flow_actions *sf_acts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) call_rcu(&sf_acts->rcu, __ovs_nla_free_flow_actions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) static struct nlattr *reserve_sfa_size(struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) int attr_len, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) struct sw_flow_actions *acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) int new_acts_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) size_t req_size = NLA_ALIGN(attr_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) int next_offset = offsetof(struct sw_flow_actions, actions) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) (*sfa)->actions_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) if (req_size <= (ksize(*sfa) - next_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) new_acts_size = max(next_offset + req_size, ksize(*sfa) * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) if (new_acts_size > MAX_ACTIONS_BUFSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) if ((MAX_ACTIONS_BUFSIZE - next_offset) < req_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) OVS_NLERR(log, "Flow action size exceeds max %u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) MAX_ACTIONS_BUFSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) return ERR_PTR(-EMSGSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) new_acts_size = MAX_ACTIONS_BUFSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) acts = nla_alloc_flow_actions(new_acts_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) if (IS_ERR(acts))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) return (void *)acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) memcpy(acts->actions, (*sfa)->actions, (*sfa)->actions_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) acts->actions_len = (*sfa)->actions_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) acts->orig_len = (*sfa)->orig_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) kfree(*sfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) *sfa = acts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) (*sfa)->actions_len += req_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) return (struct nlattr *) ((unsigned char *)(*sfa) + next_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) static struct nlattr *__add_action(struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) int attrtype, void *data, int len, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) a = reserve_sfa_size(sfa, nla_attr_size(len), log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) if (IS_ERR(a))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) a->nla_type = attrtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) a->nla_len = nla_attr_size(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) if (data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) memcpy(nla_data(a), data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) memset((unsigned char *) a + a->nla_len, 0, nla_padlen(len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) int ovs_nla_add_action(struct sw_flow_actions **sfa, int attrtype, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) int len, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) a = __add_action(sfa, attrtype, data, len, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) return PTR_ERR_OR_ZERO(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) static inline int add_nested_action_start(struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) int attrtype, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) int used = (*sfa)->actions_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) err = ovs_nla_add_action(sfa, attrtype, NULL, 0, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) return used;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) static inline void add_nested_action_end(struct sw_flow_actions *sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) int st_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) struct nlattr *a = (struct nlattr *) ((unsigned char *)sfa->actions +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) st_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) a->nla_len = sfa->actions_len - st_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) __be16 eth_type, __be16 vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) u32 mpls_label_count, bool log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) static int validate_and_copy_sample(struct net *net, const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) __be16 eth_type, __be16 vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) u32 mpls_label_count, bool log, bool last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) const struct nlattr *attrs[OVS_SAMPLE_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) const struct nlattr *probability, *actions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) const struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) int rem, start, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) struct sample_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) memset(attrs, 0, sizeof(attrs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) nla_for_each_nested(a, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) if (!type || type > OVS_SAMPLE_ATTR_MAX || attrs[type])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) attrs[type] = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) if (rem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) probability = attrs[OVS_SAMPLE_ATTR_PROBABILITY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) if (!probability || nla_len(probability) != sizeof(u32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) actions = attrs[OVS_SAMPLE_ATTR_ACTIONS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) if (!actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) /* validation done, copy sample action. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SAMPLE, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) if (start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) return start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) /* When both skb and flow may be changed, put the sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) * into a deferred fifo. On the other hand, if only skb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) * may be modified, the actions can be executed in place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) * Do this analysis at the flow installation time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) * Set 'clone_action->exec' to true if the actions can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) * executed without being deferred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) * If the sample is the last action, it can always be excuted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) * rather than deferred.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) arg.exec = last || !actions_may_change_flow(actions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) arg.probability = nla_get_u32(probability);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) err = ovs_nla_add_action(sfa, OVS_SAMPLE_ATTR_ARG, &arg, sizeof(arg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) err = __ovs_nla_copy_actions(net, actions, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) eth_type, vlan_tci, mpls_label_count, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) add_nested_action_end(*sfa, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) static int validate_and_copy_dec_ttl(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) __be16 eth_type, __be16 vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) u32 mpls_label_count, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) const struct nlattr *attrs[OVS_DEC_TTL_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) int start, action_start, err, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) const struct nlattr *a, *actions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) memset(attrs, 0, sizeof(attrs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) nla_for_each_nested(a, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) /* Ignore unknown attributes to be future proof. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) if (type > OVS_DEC_TTL_ATTR_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) if (!type || attrs[type])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) attrs[type] = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) actions = attrs[OVS_DEC_TTL_ATTR_ACTION];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) if (rem || !actions || (nla_len(actions) && nla_len(actions) < NLA_HDRLEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) start = add_nested_action_start(sfa, OVS_ACTION_ATTR_DEC_TTL, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) if (start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) return start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) action_start = add_nested_action_start(sfa, OVS_DEC_TTL_ATTR_ACTION, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) if (action_start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) return action_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) err = __ovs_nla_copy_actions(net, actions, key, sfa, eth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) vlan_tci, mpls_label_count, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) add_nested_action_end(*sfa, action_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) add_nested_action_end(*sfa, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) static int validate_and_copy_clone(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) __be16 eth_type, __be16 vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) u32 mpls_label_count, bool log, bool last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) int start, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) u32 exec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) if (nla_len(attr) && nla_len(attr) < NLA_HDRLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) start = add_nested_action_start(sfa, OVS_ACTION_ATTR_CLONE, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) if (start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) return start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) exec = last || !actions_may_change_flow(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) err = ovs_nla_add_action(sfa, OVS_CLONE_ATTR_EXEC, &exec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) sizeof(exec), log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) err = __ovs_nla_copy_actions(net, attr, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) eth_type, vlan_tci, mpls_label_count, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) add_nested_action_end(*sfa, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) void ovs_match_init(struct sw_flow_match *match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) bool reset_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) struct sw_flow_mask *mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) memset(match, 0, sizeof(*match));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) match->key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) match->mask = mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) if (reset_key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) memset(key, 0, sizeof(*key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) if (mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) memset(&mask->key, 0, sizeof(mask->key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) mask->range.start = mask->range.end = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) static int validate_geneve_opts(struct sw_flow_key *key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) struct geneve_opt *option;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) int opts_len = key->tun_opts_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) bool crit_opt = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) option = (struct geneve_opt *)TUN_METADATA_OPTS(key, key->tun_opts_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) while (opts_len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) if (opts_len < sizeof(*option))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) len = sizeof(*option) + option->length * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) if (len > opts_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) crit_opt |= !!(option->type & GENEVE_CRIT_OPT_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) option = (struct geneve_opt *)((u8 *)option + len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) opts_len -= len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) key->tun_key.tun_flags |= crit_opt ? TUNNEL_CRIT_OPT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) static int validate_and_copy_set_tun(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) struct sw_flow_actions **sfa, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) struct sw_flow_match match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) struct sw_flow_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) struct metadata_dst *tun_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) struct ip_tunnel_info *tun_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) struct ovs_tunnel_info *ovs_tun;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) int err = 0, start, opts_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) __be16 dst_opt_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) dst_opt_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) ovs_match_init(&match, &key, true, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) opts_type = ip_tun_from_nlattr(nla_data(attr), &match, false, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) if (opts_type < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) return opts_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) if (key.tun_opts_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) switch (opts_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) err = validate_geneve_opts(&key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) dst_opt_type = TUNNEL_GENEVE_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) dst_opt_type = TUNNEL_VXLAN_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) dst_opt_type = TUNNEL_ERSPAN_OPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) start = add_nested_action_start(sfa, OVS_ACTION_ATTR_SET, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) if (start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) return start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) tun_dst = metadata_dst_alloc(key.tun_opts_len, METADATA_IP_TUNNEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) if (!tun_dst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) err = dst_cache_init(&tun_dst->u.tun_info.dst_cache, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) dst_release((struct dst_entry *)tun_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) a = __add_action(sfa, OVS_KEY_ATTR_TUNNEL_INFO, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) sizeof(*ovs_tun), log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) if (IS_ERR(a)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) dst_release((struct dst_entry *)tun_dst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) return PTR_ERR(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) ovs_tun = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) ovs_tun->tun_dst = tun_dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) tun_info = &tun_dst->u.tun_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) tun_info->mode = IP_TUNNEL_INFO_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) if (key.tun_proto == AF_INET6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) tun_info->mode |= IP_TUNNEL_INFO_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) else if (key.tun_proto == AF_INET && key.tun_key.u.ipv4.dst == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) tun_info->mode |= IP_TUNNEL_INFO_BRIDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) tun_info->key = key.tun_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) /* We need to store the options in the action itself since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) * everything else will go away after flow setup. We can append
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) * it to tun_info and then point there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) ip_tunnel_info_opts_set(tun_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) TUN_METADATA_OPTS(&key, key.tun_opts_len),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) key.tun_opts_len, dst_opt_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) add_nested_action_end(*sfa, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) static bool validate_nsh(const struct nlattr *attr, bool is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) bool is_push_nsh, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) struct sw_flow_match match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) struct sw_flow_key key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) ovs_match_init(&match, &key, true, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) ret = nsh_key_put_from_nlattr(attr, &match, is_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) is_push_nsh, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) return !ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) /* Return false if there are any non-masked bits set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) * Mask follows data immediately, before any netlink padding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) static bool validate_masked(u8 *data, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) u8 *mask = data + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) while (len--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) if (*data++ & ~*mask++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) static int validate_set(const struct nlattr *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) const struct sw_flow_key *flow_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) struct sw_flow_actions **sfa, bool *skip_copy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) u8 mac_proto, __be16 eth_type, bool masked, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) const struct nlattr *ovs_key = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) int key_type = nla_type(ovs_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) size_t key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) /* There can be only one key in a action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) if (nla_total_size(nla_len(ovs_key)) != nla_len(a))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) key_len = nla_len(ovs_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) if (masked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) key_len /= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) if (key_type > OVS_KEY_ATTR_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) !check_attr_len(key_len, ovs_key_lens[key_type].len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) if (masked && !validate_masked(nla_data(ovs_key), key_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) switch (key_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) case OVS_KEY_ATTR_PRIORITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) case OVS_KEY_ATTR_SKB_MARK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) case OVS_KEY_ATTR_CT_MARK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) case OVS_KEY_ATTR_CT_LABELS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) case OVS_KEY_ATTR_ETHERNET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) if (mac_proto != MAC_PROTO_ETHERNET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) case OVS_KEY_ATTR_TUNNEL: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) if (masked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) return -EINVAL; /* Masked tunnel set not supported. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) *skip_copy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) err = validate_and_copy_set_tun(a, sfa, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) case OVS_KEY_ATTR_IPV4: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) const struct ovs_key_ipv4 *ipv4_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) if (eth_type != htons(ETH_P_IP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) ipv4_key = nla_data(ovs_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) if (masked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) const struct ovs_key_ipv4 *mask = ipv4_key + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) /* Non-writeable fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) if (mask->ipv4_proto || mask->ipv4_frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) if (ipv4_key->ipv4_proto != flow_key->ip.proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) if (ipv4_key->ipv4_frag != flow_key->ip.frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) case OVS_KEY_ATTR_IPV6: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) const struct ovs_key_ipv6 *ipv6_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) if (eth_type != htons(ETH_P_IPV6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) ipv6_key = nla_data(ovs_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) if (masked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) const struct ovs_key_ipv6 *mask = ipv6_key + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) /* Non-writeable fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) if (mask->ipv6_proto || mask->ipv6_frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) /* Invalid bits in the flow label mask? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) if (ntohl(mask->ipv6_label) & 0xFFF00000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) if (ipv6_key->ipv6_proto != flow_key->ip.proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) if (ipv6_key->ipv6_frag != flow_key->ip.frag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) if (ntohl(ipv6_key->ipv6_label) & 0xFFF00000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) case OVS_KEY_ATTR_TCP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) if ((eth_type != htons(ETH_P_IP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) eth_type != htons(ETH_P_IPV6)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) flow_key->ip.proto != IPPROTO_TCP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) case OVS_KEY_ATTR_UDP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) if ((eth_type != htons(ETH_P_IP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) eth_type != htons(ETH_P_IPV6)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) flow_key->ip.proto != IPPROTO_UDP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) case OVS_KEY_ATTR_MPLS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) if (!eth_p_mpls(eth_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) case OVS_KEY_ATTR_SCTP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) if ((eth_type != htons(ETH_P_IP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) eth_type != htons(ETH_P_IPV6)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) flow_key->ip.proto != IPPROTO_SCTP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) case OVS_KEY_ATTR_NSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) if (eth_type != htons(ETH_P_NSH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) if (!validate_nsh(nla_data(a), masked, false, log))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) /* Convert non-masked non-tunnel set actions to masked set actions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) if (!masked && key_type != OVS_KEY_ATTR_TUNNEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) int start, len = key_len * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) struct nlattr *at;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) *skip_copy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) start = add_nested_action_start(sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) OVS_ACTION_ATTR_SET_TO_MASKED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) if (start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) return start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) at = __add_action(sfa, key_type, NULL, len, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) if (IS_ERR(at))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) return PTR_ERR(at);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) memcpy(nla_data(at), nla_data(ovs_key), key_len); /* Key. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) memset(nla_data(at) + key_len, 0xff, key_len); /* Mask. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) /* Clear non-writeable bits from otherwise writeable fields. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) if (key_type == OVS_KEY_ATTR_IPV6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) struct ovs_key_ipv6 *mask = nla_data(at) + key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) mask->ipv6_label &= htonl(0x000FFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) add_nested_action_end(*sfa, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) static int validate_userspace(const struct nlattr *attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) static const struct nla_policy userspace_policy[OVS_USERSPACE_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) [OVS_USERSPACE_ATTR_PID] = {.type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) [OVS_USERSPACE_ATTR_USERDATA] = {.type = NLA_UNSPEC },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) [OVS_USERSPACE_ATTR_EGRESS_TUN_PORT] = {.type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) struct nlattr *a[OVS_USERSPACE_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) error = nla_parse_nested_deprecated(a, OVS_USERSPACE_ATTR_MAX, attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) userspace_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) if (!a[OVS_USERSPACE_ATTR_PID] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) !nla_get_u32(a[OVS_USERSPACE_ATTR_PID]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) static const struct nla_policy cpl_policy[OVS_CHECK_PKT_LEN_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) [OVS_CHECK_PKT_LEN_ATTR_PKT_LEN] = {.type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER] = {.type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) [OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL] = {.type = NLA_NESTED },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) static int validate_and_copy_check_pkt_len(struct net *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) __be16 eth_type, __be16 vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) u32 mpls_label_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) bool log, bool last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) const struct nlattr *acts_if_greater, *acts_if_lesser_eq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) struct nlattr *a[OVS_CHECK_PKT_LEN_ATTR_MAX + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) struct check_pkt_len_arg arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) int nested_acts_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) int start, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) err = nla_parse_deprecated_strict(a, OVS_CHECK_PKT_LEN_ATTR_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) nla_data(attr), nla_len(attr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) cpl_policy, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) if (!a[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN] ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) !nla_get_u16(a[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) acts_if_lesser_eq = a[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) acts_if_greater = a[OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) /* Both the nested action should be present. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) if (!acts_if_greater || !acts_if_lesser_eq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) /* validation done, copy the nested actions. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) start = add_nested_action_start(sfa, OVS_ACTION_ATTR_CHECK_PKT_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) if (start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) return start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) arg.pkt_len = nla_get_u16(a[OVS_CHECK_PKT_LEN_ATTR_PKT_LEN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) arg.exec_for_lesser_equal =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) last || !actions_may_change_flow(acts_if_lesser_eq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) arg.exec_for_greater =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) last || !actions_may_change_flow(acts_if_greater);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) err = ovs_nla_add_action(sfa, OVS_CHECK_PKT_LEN_ATTR_ARG, &arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) sizeof(arg), log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) nested_acts_start = add_nested_action_start(sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) if (nested_acts_start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) return nested_acts_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) err = __ovs_nla_copy_actions(net, acts_if_lesser_eq, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) eth_type, vlan_tci, mpls_label_count, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) add_nested_action_end(*sfa, nested_acts_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) nested_acts_start = add_nested_action_start(sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) if (nested_acts_start < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) return nested_acts_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) err = __ovs_nla_copy_actions(net, acts_if_greater, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) eth_type, vlan_tci, mpls_label_count, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) add_nested_action_end(*sfa, nested_acts_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) add_nested_action_end(*sfa, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) static int copy_action(const struct nlattr *from,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) struct sw_flow_actions **sfa, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) int totlen = NLA_ALIGN(from->nla_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) struct nlattr *to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) to = reserve_sfa_size(sfa, from->nla_len, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) if (IS_ERR(to))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) return PTR_ERR(to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) memcpy(to, from, totlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) static int __ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) struct sw_flow_actions **sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) __be16 eth_type, __be16 vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) u32 mpls_label_count, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) u8 mac_proto = ovs_key_mac_proto(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) const struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) int rem, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) nla_for_each_nested(a, attr, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) /* Expected argument lengths, (u32)-1 for variable length. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) static const u32 action_lens[OVS_ACTION_ATTR_MAX + 1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) [OVS_ACTION_ATTR_OUTPUT] = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) [OVS_ACTION_ATTR_RECIRC] = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) [OVS_ACTION_ATTR_USERSPACE] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) [OVS_ACTION_ATTR_PUSH_MPLS] = sizeof(struct ovs_action_push_mpls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) [OVS_ACTION_ATTR_POP_MPLS] = sizeof(__be16),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) [OVS_ACTION_ATTR_PUSH_VLAN] = sizeof(struct ovs_action_push_vlan),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) [OVS_ACTION_ATTR_POP_VLAN] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) [OVS_ACTION_ATTR_SET] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) [OVS_ACTION_ATTR_SET_MASKED] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) [OVS_ACTION_ATTR_SAMPLE] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) [OVS_ACTION_ATTR_HASH] = sizeof(struct ovs_action_hash),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) [OVS_ACTION_ATTR_CT] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) [OVS_ACTION_ATTR_CT_CLEAR] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) [OVS_ACTION_ATTR_TRUNC] = sizeof(struct ovs_action_trunc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) [OVS_ACTION_ATTR_PUSH_ETH] = sizeof(struct ovs_action_push_eth),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) [OVS_ACTION_ATTR_POP_ETH] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) [OVS_ACTION_ATTR_PUSH_NSH] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) [OVS_ACTION_ATTR_POP_NSH] = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) [OVS_ACTION_ATTR_METER] = sizeof(u32),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) [OVS_ACTION_ATTR_CLONE] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) [OVS_ACTION_ATTR_CHECK_PKT_LEN] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) [OVS_ACTION_ATTR_ADD_MPLS] = sizeof(struct ovs_action_add_mpls),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) [OVS_ACTION_ATTR_DEC_TTL] = (u32)-1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) const struct ovs_action_push_vlan *vlan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) bool skip_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) if (type > OVS_ACTION_ATTR_MAX ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) (action_lens[type] != nla_len(a) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) action_lens[type] != (u32)-1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) skip_copy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) case OVS_ACTION_ATTR_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) case OVS_ACTION_ATTR_USERSPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) err = validate_userspace(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) case OVS_ACTION_ATTR_OUTPUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) if (nla_get_u32(a) >= DP_MAX_PORTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) case OVS_ACTION_ATTR_TRUNC: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) const struct ovs_action_trunc *trunc = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) if (trunc->max_len < ETH_HLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) case OVS_ACTION_ATTR_HASH: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) const struct ovs_action_hash *act_hash = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) switch (act_hash->hash_alg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) case OVS_HASH_ALG_L4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) case OVS_ACTION_ATTR_POP_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) if (mac_proto != MAC_PROTO_ETHERNET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) vlan_tci = htons(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) case OVS_ACTION_ATTR_PUSH_VLAN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) if (mac_proto != MAC_PROTO_ETHERNET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) vlan = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) if (!eth_type_vlan(vlan->vlan_tpid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) if (!(vlan->vlan_tci & htons(VLAN_CFI_MASK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) vlan_tci = vlan->vlan_tci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) case OVS_ACTION_ATTR_RECIRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) case OVS_ACTION_ATTR_ADD_MPLS: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) const struct ovs_action_add_mpls *mpls = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) if (!eth_p_mpls(mpls->mpls_ethertype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) if (mpls->tun_flags & OVS_MPLS_L3_TUNNEL_FLAG_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) if (vlan_tci & htons(VLAN_CFI_MASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) (eth_type != htons(ETH_P_IP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) eth_type != htons(ETH_P_IPV6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) eth_type != htons(ETH_P_ARP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) eth_type != htons(ETH_P_RARP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) !eth_p_mpls(eth_type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) mpls_label_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) if (mac_proto == MAC_PROTO_ETHERNET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) mpls_label_count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) mac_proto = MAC_PROTO_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) mpls_label_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) eth_type = mpls->mpls_ethertype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) case OVS_ACTION_ATTR_PUSH_MPLS: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) const struct ovs_action_push_mpls *mpls = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) if (!eth_p_mpls(mpls->mpls_ethertype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) /* Prohibit push MPLS other than to a white list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) * for packets that have a known tag order.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) if (vlan_tci & htons(VLAN_CFI_MASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) (eth_type != htons(ETH_P_IP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) eth_type != htons(ETH_P_IPV6) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) eth_type != htons(ETH_P_ARP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) eth_type != htons(ETH_P_RARP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) !eth_p_mpls(eth_type)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) eth_type = mpls->mpls_ethertype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) mpls_label_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) case OVS_ACTION_ATTR_POP_MPLS: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) __be16 proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) if (vlan_tci & htons(VLAN_CFI_MASK) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) !eth_p_mpls(eth_type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) /* Disallow subsequent L2.5+ set actions and mpls_pop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) * actions once the last MPLS label in the packet is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) * is popped as there is no check here to ensure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) * the new eth type is valid and thus set actions could
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) * write off the end of the packet or otherwise corrupt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) * it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) * Support for these actions is planned using packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) * recirculation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) proto = nla_get_be16(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) if (proto == htons(ETH_P_TEB) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) mac_proto != MAC_PROTO_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) mpls_label_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) if (!eth_p_mpls(proto) || !mpls_label_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) eth_type = htons(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) eth_type = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) case OVS_ACTION_ATTR_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) err = validate_set(a, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) &skip_copy, mac_proto, eth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) false, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) case OVS_ACTION_ATTR_SET_MASKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) err = validate_set(a, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) &skip_copy, mac_proto, eth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) true, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) case OVS_ACTION_ATTR_SAMPLE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) bool last = nla_is_last(a, rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) err = validate_and_copy_sample(net, a, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) eth_type, vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) mpls_label_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) log, last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) skip_copy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) case OVS_ACTION_ATTR_CT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) err = ovs_ct_copy_action(net, a, key, sfa, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) skip_copy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) case OVS_ACTION_ATTR_CT_CLEAR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) case OVS_ACTION_ATTR_PUSH_ETH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) /* Disallow pushing an Ethernet header if one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) * is already present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) if (mac_proto != MAC_PROTO_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) mac_proto = MAC_PROTO_ETHERNET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) case OVS_ACTION_ATTR_POP_ETH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) if (mac_proto != MAC_PROTO_ETHERNET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) if (vlan_tci & htons(VLAN_CFI_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) mac_proto = MAC_PROTO_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) case OVS_ACTION_ATTR_PUSH_NSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) if (mac_proto != MAC_PROTO_ETHERNET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) u8 next_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) next_proto = tun_p_from_eth_p(eth_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) if (!next_proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) mac_proto = MAC_PROTO_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) if (!validate_nsh(nla_data(a), false, true, true))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) case OVS_ACTION_ATTR_POP_NSH: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) __be16 inner_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) if (eth_type != htons(ETH_P_NSH))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) inner_proto = tun_p_to_eth_p(key->nsh.base.np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) if (!inner_proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) if (key->nsh.base.np == TUN_P_ETHERNET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) mac_proto = MAC_PROTO_ETHERNET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) mac_proto = MAC_PROTO_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) case OVS_ACTION_ATTR_METER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) /* Non-existent meters are simply ignored. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) case OVS_ACTION_ATTR_CLONE: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) bool last = nla_is_last(a, rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) err = validate_and_copy_clone(net, a, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) eth_type, vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) mpls_label_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) log, last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) skip_copy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) case OVS_ACTION_ATTR_CHECK_PKT_LEN: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) bool last = nla_is_last(a, rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) err = validate_and_copy_check_pkt_len(net, a, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) eth_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) mpls_label_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) log, last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) skip_copy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) case OVS_ACTION_ATTR_DEC_TTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) err = validate_and_copy_dec_ttl(net, a, key, sfa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) eth_type, vlan_tci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) mpls_label_count, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) skip_copy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) OVS_NLERR(log, "Unknown Action type %d", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) if (!skip_copy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) err = copy_action(a, sfa, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) if (rem > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) /* 'key' must be the masked key. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) int ovs_nla_copy_actions(struct net *net, const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) const struct sw_flow_key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) struct sw_flow_actions **sfa, bool log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) u32 mpls_label_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) *sfa = nla_alloc_flow_actions(min(nla_len(attr), MAX_ACTIONS_BUFSIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) if (IS_ERR(*sfa))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) return PTR_ERR(*sfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) if (eth_p_mpls(key->eth.type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) mpls_label_count = hweight_long(key->mpls.num_labels_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) (*sfa)->orig_len = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) err = __ovs_nla_copy_actions(net, attr, key, sfa, key->eth.type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) key->eth.vlan.tci, mpls_label_count, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) ovs_nla_free_flow_actions(*sfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) static int sample_action_to_attr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) struct nlattr *start, *ac_start = NULL, *sample_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) int err = 0, rem = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) const struct sample_arg *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) struct nlattr *actions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_SAMPLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) if (!start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) sample_arg = nla_data(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) arg = nla_data(sample_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) actions = nla_next(sample_arg, &rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) if (nla_put_u32(skb, OVS_SAMPLE_ATTR_PROBABILITY, arg->probability)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) ac_start = nla_nest_start_noflag(skb, OVS_SAMPLE_ATTR_ACTIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) if (!ac_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) err = ovs_nla_put_actions(actions, rem, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) nla_nest_cancel(skb, ac_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) nla_nest_cancel(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) nla_nest_end(skb, ac_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) nla_nest_end(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) static int clone_action_to_attr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) struct nlattr *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) int err = 0, rem = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_CLONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) if (!start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) err = ovs_nla_put_actions(nla_data(attr), rem, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) nla_nest_cancel(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) nla_nest_end(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) static int check_pkt_len_action_to_attr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) struct nlattr *start, *ac_start = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) const struct check_pkt_len_arg *arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) const struct nlattr *a, *cpl_arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) int err = 0, rem = nla_len(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_CHECK_PKT_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) if (!start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) /* The first nested attribute in 'attr' is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) * 'OVS_CHECK_PKT_LEN_ATTR_ARG'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) cpl_arg = nla_data(attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) arg = nla_data(cpl_arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) if (nla_put_u16(skb, OVS_CHECK_PKT_LEN_ATTR_PKT_LEN, arg->pkt_len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) /* Second nested attribute in 'attr' is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) * 'OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) a = nla_next(cpl_arg, &rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) ac_start = nla_nest_start_noflag(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_LESS_EQUAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) if (!ac_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) nla_nest_cancel(skb, ac_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) nla_nest_end(skb, ac_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) /* Third nested attribute in 'attr' is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) * OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) a = nla_next(a, &rem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) ac_start = nla_nest_start_noflag(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) OVS_CHECK_PKT_LEN_ATTR_ACTIONS_IF_GREATER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) if (!ac_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) nla_nest_cancel(skb, ac_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) nla_nest_end(skb, ac_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) nla_nest_end(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) nla_nest_cancel(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) static int dec_ttl_action_to_attr(const struct nlattr *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) struct nlattr *start, *action_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) const struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) int err = 0, rem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_DEC_TTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) if (!start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) nla_for_each_attr(a, nla_data(attr), nla_len(attr), rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) switch (nla_type(a)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) case OVS_DEC_TTL_ATTR_ACTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) action_start = nla_nest_start_noflag(skb, OVS_DEC_TTL_ATTR_ACTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) if (!action_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) err = -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) err = ovs_nla_put_actions(nla_data(a), nla_len(a), skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) nla_nest_end(skb, action_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) /* Ignore all other option to be future compatible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) nla_nest_end(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) nla_nest_cancel(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) const struct nlattr *ovs_key = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) int key_type = nla_type(ovs_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) struct nlattr *start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) switch (key_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) case OVS_KEY_ATTR_TUNNEL_INFO: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) struct ovs_tunnel_info *ovs_tun = nla_data(ovs_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) struct ip_tunnel_info *tun_info = &ovs_tun->tun_dst->u.tun_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) if (!start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) err = ip_tun_to_nlattr(skb, &tun_info->key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) ip_tunnel_info_opts(tun_info),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) tun_info->options_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) ip_tunnel_info_af(tun_info), tun_info->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) nla_nest_end(skb, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a), ovs_key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) static int masked_set_action_to_set_action_attr(const struct nlattr *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) const struct nlattr *ovs_key = nla_data(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) struct nlattr *nla;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) size_t key_len = nla_len(ovs_key) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) /* Revert the conversion we did from a non-masked set action to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) * masked set action.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) nla = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_SET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) if (!nla)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) if (nla_put(skb, nla_type(ovs_key), key_len, nla_data(ovs_key)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) nla_nest_end(skb, nla);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) int ovs_nla_put_actions(const struct nlattr *attr, int len, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) const struct nlattr *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) int rem, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) nla_for_each_attr(a, attr, len, rem) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) int type = nla_type(a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) case OVS_ACTION_ATTR_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) err = set_action_to_attr(a, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) case OVS_ACTION_ATTR_SET_TO_MASKED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) err = masked_set_action_to_set_action_attr(a, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) case OVS_ACTION_ATTR_SAMPLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) err = sample_action_to_attr(a, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) case OVS_ACTION_ATTR_CT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) err = ovs_ct_action_to_attr(nla_data(a), skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) case OVS_ACTION_ATTR_CLONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) err = clone_action_to_attr(a, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) case OVS_ACTION_ATTR_CHECK_PKT_LEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) err = check_pkt_len_action_to_attr(a, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) case OVS_ACTION_ATTR_DEC_TTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) err = dec_ttl_action_to_attr(a, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) if (nla_put(skb, type, nla_len(a), nla_data(a)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) }