]>
git.proxmox.com Git - mirror_ovs.git/blob - ovn/lib/logical-fields.c
1 /* Copyright (c) 2016 Nicira, Inc.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
18 #include "logical-fields.h"
20 #include "openvswitch/shash.h"
22 #include "ovs-thread.h"
26 add_subregister(const char *name
,
27 const char *parent_name
, int parent_idx
,
31 int lsb
= width
* idx
;
32 int msb
= lsb
+ (width
- 1);
33 char *expansion
= xasprintf("%s%d[%d..%d]",
34 parent_name
, parent_idx
, lsb
, msb
);
35 expr_symtab_add_subfield(symtab
, name
, NULL
, expansion
);
40 ovn_init_symtab(struct shash
*symtab
)
44 /* Reserve a pair of registers for the logical inport and outport. A full
45 * 32-bit register each is bigger than we need, but the expression code
46 * doesn't yet support string fields that occupy less than a full OXM. */
47 expr_symtab_add_string(symtab
, "inport", MFF_LOG_INPORT
, NULL
);
48 expr_symtab_add_string(symtab
, "outport", MFF_LOG_OUTPORT
, NULL
);
55 * The expression language doesn't handle overlapping fields properly
56 * unless they're formally defined as subfields. It's a little awkward. */
57 for (int xxi
= 0; xxi
< MFF_N_LOG_REGS
/ 4; xxi
++) {
58 char *xxname
= xasprintf("xxreg%d", xxi
);
59 expr_symtab_add_field(symtab
, xxname
, MFF_XXREG0
+ xxi
, NULL
, false);
62 for (int xi
= 0; xi
< MFF_N_LOG_REGS
/ 2; xi
++) {
63 char *xname
= xasprintf("xreg%d", xi
);
65 if (xxi
< MFF_N_LOG_REGS
/ 4) {
66 add_subregister(xname
, "xxreg", xxi
, 64, 1 - xi
% 2, symtab
);
68 expr_symtab_add_field(symtab
, xname
, MFF_XREG0
+ xi
, NULL
, false);
72 for (int i
= 0; i
< MFF_N_LOG_REGS
; i
++) {
73 char *name
= xasprintf("reg%d", i
);
76 if (xxi
< MFF_N_LOG_REGS
/ 4) {
77 add_subregister(name
, "xxreg", xxi
, 32, 3 - i
% 4, symtab
);
78 } else if (xi
< MFF_N_LOG_REGS
/ 2) {
79 add_subregister(name
, "xreg", xi
, 32, 1 - i
% 2, symtab
);
81 expr_symtab_add_field(symtab
, name
, MFF_REG0
+ i
, NULL
, false);
86 /* Flags used in logical to physical transformation. */
87 expr_symtab_add_field(symtab
, "flags", MFF_LOG_FLAGS
, NULL
, false);
89 snprintf(flags_str
, sizeof flags_str
, "flags[%d]", MLF_ALLOW_LOOPBACK_BIT
);
90 expr_symtab_add_subfield(symtab
, "flags.loopback", NULL
, flags_str
);
92 /* Connection tracking state. */
93 expr_symtab_add_field(symtab
, "ct_mark", MFF_CT_MARK
, NULL
, false);
95 expr_symtab_add_field(symtab
, "ct_label", MFF_CT_LABEL
, NULL
, false);
96 expr_symtab_add_subfield(symtab
, "ct_label.blocked", NULL
, "ct_label[0]");
98 expr_symtab_add_field(symtab
, "ct_state", MFF_CT_STATE
, NULL
, false);
104 static const struct ct_bit bits
[] = {
105 {"trk", CS_TRACKED_BIT
},
107 {"est", CS_ESTABLISHED_BIT
},
108 {"rel", CS_RELATED_BIT
},
109 {"rpl", CS_REPLY_DIR_BIT
},
110 {"inv", CS_INVALID_BIT
},
112 for (const struct ct_bit
*b
= bits
; b
< &bits
[ARRAY_SIZE(bits
)]; b
++) {
113 char *name
= xasprintf("ct.%s", b
->name
);
114 char *expansion
= xasprintf("ct_state[%d]", b
->bit
);
115 const char *prereqs
= b
->bit
== CS_TRACKED_BIT
? NULL
: "ct.trk";
116 expr_symtab_add_subfield(symtab
, name
, prereqs
, expansion
);
122 expr_symtab_add_field(symtab
, "eth.src", MFF_ETH_SRC
, NULL
, false);
123 expr_symtab_add_field(symtab
, "eth.dst", MFF_ETH_DST
, NULL
, false);
124 expr_symtab_add_field(symtab
, "eth.type", MFF_ETH_TYPE
, NULL
, true);
125 expr_symtab_add_predicate(symtab
, "eth.bcast",
126 "eth.dst == ff:ff:ff:ff:ff:ff");
127 expr_symtab_add_subfield(symtab
, "eth.mcast", NULL
, "eth.dst[40]");
129 expr_symtab_add_field(symtab
, "vlan.tci", MFF_VLAN_TCI
, NULL
, false);
130 expr_symtab_add_predicate(symtab
, "vlan.present", "vlan.tci[12]");
131 expr_symtab_add_subfield(symtab
, "vlan.pcp", "vlan.present",
133 expr_symtab_add_subfield(symtab
, "vlan.vid", "vlan.present",
136 expr_symtab_add_predicate(symtab
, "ip4", "eth.type == 0x800");
137 expr_symtab_add_predicate(symtab
, "ip6", "eth.type == 0x86dd");
138 expr_symtab_add_predicate(symtab
, "ip", "ip4 || ip6");
139 expr_symtab_add_field(symtab
, "ip.proto", MFF_IP_PROTO
, "ip", true);
140 expr_symtab_add_field(symtab
, "ip.dscp", MFF_IP_DSCP
, "ip", false);
141 expr_symtab_add_field(symtab
, "ip.ecn", MFF_IP_ECN
, "ip", false);
142 expr_symtab_add_field(symtab
, "ip.ttl", MFF_IP_TTL
, "ip", false);
144 expr_symtab_add_field(symtab
, "ip4.src", MFF_IPV4_SRC
, "ip4", false);
145 expr_symtab_add_field(symtab
, "ip4.dst", MFF_IPV4_DST
, "ip4", false);
146 expr_symtab_add_predicate(symtab
, "ip4.mcast", "ip4.dst[28..31] == 0xe");
148 expr_symtab_add_predicate(symtab
, "icmp4", "ip4 && ip.proto == 1");
149 expr_symtab_add_field(symtab
, "icmp4.type", MFF_ICMPV4_TYPE
, "icmp4",
151 expr_symtab_add_field(symtab
, "icmp4.code", MFF_ICMPV4_CODE
, "icmp4",
154 expr_symtab_add_field(symtab
, "ip6.src", MFF_IPV6_SRC
, "ip6", false);
155 expr_symtab_add_field(symtab
, "ip6.dst", MFF_IPV6_DST
, "ip6", false);
156 expr_symtab_add_field(symtab
, "ip6.label", MFF_IPV6_LABEL
, "ip6", false);
158 expr_symtab_add_predicate(symtab
, "icmp6", "ip6 && ip.proto == 58");
159 expr_symtab_add_field(symtab
, "icmp6.type", MFF_ICMPV6_TYPE
, "icmp6",
161 expr_symtab_add_field(symtab
, "icmp6.code", MFF_ICMPV6_CODE
, "icmp6",
164 expr_symtab_add_predicate(symtab
, "icmp", "icmp4 || icmp6");
166 expr_symtab_add_field(symtab
, "ip.frag", MFF_IP_FRAG
, "ip", false);
167 expr_symtab_add_predicate(symtab
, "ip.is_frag", "ip.frag[0]");
168 expr_symtab_add_predicate(symtab
, "ip.later_frag", "ip.frag[1]");
169 expr_symtab_add_predicate(symtab
, "ip.first_frag",
170 "ip.is_frag && !ip.later_frag");
172 expr_symtab_add_predicate(symtab
, "arp", "eth.type == 0x806");
173 expr_symtab_add_field(symtab
, "arp.op", MFF_ARP_OP
, "arp", false);
174 expr_symtab_add_field(symtab
, "arp.spa", MFF_ARP_SPA
, "arp", false);
175 expr_symtab_add_field(symtab
, "arp.sha", MFF_ARP_SHA
, "arp", false);
176 expr_symtab_add_field(symtab
, "arp.tpa", MFF_ARP_TPA
, "arp", false);
177 expr_symtab_add_field(symtab
, "arp.tha", MFF_ARP_THA
, "arp", false);
179 expr_symtab_add_predicate(symtab
, "nd",
180 "icmp6.type == {135, 136} && icmp6.code == 0 && ip.ttl == 255");
181 expr_symtab_add_predicate(symtab
, "nd_ns",
182 "icmp6.type == 135 && icmp6.code == 0 && ip.ttl == 255");
183 expr_symtab_add_predicate(symtab
, "nd_na",
184 "icmp6.type == 136 && icmp6.code == 0 && ip.ttl == 255");
185 expr_symtab_add_field(symtab
, "nd.target", MFF_ND_TARGET
, "nd", false);
186 expr_symtab_add_field(symtab
, "nd.sll", MFF_ND_SLL
, "nd_ns", false);
187 expr_symtab_add_field(symtab
, "nd.tll", MFF_ND_TLL
, "nd_na", false);
189 expr_symtab_add_predicate(symtab
, "tcp", "ip.proto == 6");
190 expr_symtab_add_field(symtab
, "tcp.src", MFF_TCP_SRC
, "tcp", false);
191 expr_symtab_add_field(symtab
, "tcp.dst", MFF_TCP_DST
, "tcp", false);
192 expr_symtab_add_field(symtab
, "tcp.flags", MFF_TCP_FLAGS
, "tcp", false);
194 expr_symtab_add_predicate(symtab
, "udp", "ip.proto == 17");
195 expr_symtab_add_field(symtab
, "udp.src", MFF_UDP_SRC
, "udp", false);
196 expr_symtab_add_field(symtab
, "udp.dst", MFF_UDP_DST
, "udp", false);
198 expr_symtab_add_predicate(symtab
, "sctp", "ip.proto == 132");
199 expr_symtab_add_field(symtab
, "sctp.src", MFF_SCTP_SRC
, "sctp", false);
200 expr_symtab_add_field(symtab
, "sctp.dst", MFF_SCTP_DST
, "sctp", false);