Branch data Line data Source code
1 : : /* Copyright (c) 2016 Nicira, Inc.
2 : : *
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:
6 : : *
7 : : * http://www.apache.org/licenses/LICENSE-2.0
8 : : *
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.
14 : : */
15 : :
16 : : #include <config.h>
17 : :
18 : : #include "logical-fields.h"
19 : :
20 : : #include "openvswitch/shash.h"
21 : : #include "ovn/expr.h"
22 : : #include "ovs-thread.h"
23 : : #include "packets.h"
24 : :
25 : : static void
26 : 938 : add_subregister(const char *name,
27 : : const char *parent_name, int parent_idx,
28 : : int width, int idx,
29 : : struct shash *symtab)
30 : : {
31 : 938 : int lsb = width * idx;
32 : 938 : int msb = lsb + (width - 1);
33 : 938 : char *expansion = xasprintf("%s%d[%d..%d]",
34 : : parent_name, parent_idx, lsb, msb);
35 : 938 : expr_symtab_add_subfield(symtab, name, NULL, expansion);
36 : 938 : free(expansion);
37 : 938 : }
38 : :
39 : : void
40 : 67 : ovn_init_symtab(struct shash *symtab)
41 : : {
42 : 67 : shash_init(symtab);
43 : :
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 : 67 : expr_symtab_add_string(symtab, "inport", MFF_LOG_INPORT, NULL);
48 : 67 : expr_symtab_add_string(symtab, "outport", MFF_LOG_OUTPORT, NULL);
49 : :
50 : : /* Logical registers:
51 : : * 128-bit xxregs
52 : : * 64-bit xregs
53 : : * 32-bit regs
54 : : *
55 : : * The expression language doesn't handle overlapping fields properly
56 : : * unless they're formally defined as subfields. It's a little awkward. */
57 [ + + ]: 201 : for (int xxi = 0; xxi < MFF_N_LOG_REGS / 4; xxi++) {
58 : 134 : char *xxname = xasprintf("xxreg%d", xxi);
59 : 134 : expr_symtab_add_field(symtab, xxname, MFF_XXREG0 + xxi, NULL, false);
60 : 134 : free(xxname);
61 : : }
62 [ + + ]: 402 : for (int xi = 0; xi < MFF_N_LOG_REGS / 2; xi++) {
63 : 335 : char *xname = xasprintf("xreg%d", xi);
64 : 335 : int xxi = xi / 2;
65 [ + + ]: 335 : if (xxi < MFF_N_LOG_REGS / 4) {
66 : 268 : add_subregister(xname, "xxreg", xxi, 64, 1 - xi % 2, symtab);
67 : : } else {
68 : 67 : expr_symtab_add_field(symtab, xname, MFF_XREG0 + xi, NULL, false);
69 : : }
70 : 335 : free(xname);
71 : : }
72 [ + + ]: 737 : for (int i = 0; i < MFF_N_LOG_REGS; i++) {
73 : 670 : char *name = xasprintf("reg%d", i);
74 : 670 : int xxi = i / 4;
75 : 670 : int xi = i / 2;
76 [ + + ]: 670 : if (xxi < MFF_N_LOG_REGS / 4) {
77 : 536 : add_subregister(name, "xxreg", xxi, 32, 3 - i % 4, symtab);
78 [ + - ]: 134 : } else if (xi < MFF_N_LOG_REGS / 2) {
79 : 134 : add_subregister(name, "xreg", xi, 32, 1 - i % 2, symtab);
80 : : } else {
81 : 0 : expr_symtab_add_field(symtab, name, MFF_REG0 + i, NULL, false);
82 : : }
83 : 670 : free(name);
84 : : }
85 : :
86 : : /* Flags used in logical to physical transformation. */
87 : 67 : expr_symtab_add_field(symtab, "flags", MFF_LOG_FLAGS, NULL, false);
88 : : char flags_str[16];
89 : 67 : snprintf(flags_str, sizeof flags_str, "flags[%d]", MLF_ALLOW_LOOPBACK_BIT);
90 : 67 : expr_symtab_add_subfield(symtab, "flags.loopback", NULL, flags_str);
91 : :
92 : : /* Connection tracking state. */
93 : 67 : expr_symtab_add_field(symtab, "ct_mark", MFF_CT_MARK, NULL, false);
94 : 67 : expr_symtab_add_field(symtab, "ct_label", MFF_CT_LABEL, NULL, false);
95 : 67 : expr_symtab_add_field(symtab, "ct_state", MFF_CT_STATE, NULL, false);
96 : :
97 : : struct ct_bit {
98 : : const char *name;
99 : : int bit;
100 : : };
101 : : static const struct ct_bit bits[] = {
102 : : {"trk", CS_TRACKED_BIT},
103 : : {"new", CS_NEW_BIT},
104 : : {"est", CS_ESTABLISHED_BIT},
105 : : {"rel", CS_RELATED_BIT},
106 : : {"rpl", CS_REPLY_DIR_BIT},
107 : : {"inv", CS_INVALID_BIT},
108 : : };
109 [ + + ]: 469 : for (const struct ct_bit *b = bits; b < &bits[ARRAY_SIZE(bits)]; b++) {
110 : 402 : char *name = xasprintf("ct.%s", b->name);
111 : 402 : char *expansion = xasprintf("ct_state[%d]", b->bit);
112 [ + + ]: 402 : const char *prereqs = b->bit == CS_TRACKED_BIT ? NULL : "ct.trk";
113 : 402 : expr_symtab_add_subfield(symtab, name, prereqs, expansion);
114 : 402 : free(expansion);
115 : 402 : free(name);
116 : : }
117 : :
118 : : /* Data fields. */
119 : 67 : expr_symtab_add_field(symtab, "eth.src", MFF_ETH_SRC, NULL, false);
120 : 67 : expr_symtab_add_field(symtab, "eth.dst", MFF_ETH_DST, NULL, false);
121 : 67 : expr_symtab_add_field(symtab, "eth.type", MFF_ETH_TYPE, NULL, true);
122 : 67 : expr_symtab_add_predicate(symtab, "eth.bcast",
123 : : "eth.dst == ff:ff:ff:ff:ff:ff");
124 : 67 : expr_symtab_add_subfield(symtab, "eth.mcast", NULL, "eth.dst[40]");
125 : :
126 : 67 : expr_symtab_add_field(symtab, "vlan.tci", MFF_VLAN_TCI, NULL, false);
127 : 67 : expr_symtab_add_predicate(symtab, "vlan.present", "vlan.tci[12]");
128 : 67 : expr_symtab_add_subfield(symtab, "vlan.pcp", "vlan.present",
129 : : "vlan.tci[13..15]");
130 : 67 : expr_symtab_add_subfield(symtab, "vlan.vid", "vlan.present",
131 : : "vlan.tci[0..11]");
132 : :
133 : 67 : expr_symtab_add_predicate(symtab, "ip4", "eth.type == 0x800");
134 : 67 : expr_symtab_add_predicate(symtab, "ip6", "eth.type == 0x86dd");
135 : 67 : expr_symtab_add_predicate(symtab, "ip", "ip4 || ip6");
136 : 67 : expr_symtab_add_field(symtab, "ip.proto", MFF_IP_PROTO, "ip", true);
137 : 67 : expr_symtab_add_field(symtab, "ip.dscp", MFF_IP_DSCP, "ip", false);
138 : 67 : expr_symtab_add_field(symtab, "ip.ecn", MFF_IP_ECN, "ip", false);
139 : 67 : expr_symtab_add_field(symtab, "ip.ttl", MFF_IP_TTL, "ip", false);
140 : :
141 : 67 : expr_symtab_add_field(symtab, "ip4.src", MFF_IPV4_SRC, "ip4", false);
142 : 67 : expr_symtab_add_field(symtab, "ip4.dst", MFF_IPV4_DST, "ip4", false);
143 : 67 : expr_symtab_add_predicate(symtab, "ip4.mcast", "ip4.dst[28..31] == 0xe");
144 : :
145 : 67 : expr_symtab_add_predicate(symtab, "icmp4", "ip4 && ip.proto == 1");
146 : 67 : expr_symtab_add_field(symtab, "icmp4.type", MFF_ICMPV4_TYPE, "icmp4",
147 : : false);
148 : 67 : expr_symtab_add_field(symtab, "icmp4.code", MFF_ICMPV4_CODE, "icmp4",
149 : : false);
150 : :
151 : 67 : expr_symtab_add_field(symtab, "ip6.src", MFF_IPV6_SRC, "ip6", false);
152 : 67 : expr_symtab_add_field(symtab, "ip6.dst", MFF_IPV6_DST, "ip6", false);
153 : 67 : expr_symtab_add_field(symtab, "ip6.label", MFF_IPV6_LABEL, "ip6", false);
154 : :
155 : 67 : expr_symtab_add_predicate(symtab, "icmp6", "ip6 && ip.proto == 58");
156 : 67 : expr_symtab_add_field(symtab, "icmp6.type", MFF_ICMPV6_TYPE, "icmp6",
157 : : true);
158 : 67 : expr_symtab_add_field(symtab, "icmp6.code", MFF_ICMPV6_CODE, "icmp6",
159 : : true);
160 : :
161 : 67 : expr_symtab_add_predicate(symtab, "icmp", "icmp4 || icmp6");
162 : :
163 : 67 : expr_symtab_add_field(symtab, "ip.frag", MFF_IP_FRAG, "ip", false);
164 : 67 : expr_symtab_add_predicate(symtab, "ip.is_frag", "ip.frag[0]");
165 : 67 : expr_symtab_add_predicate(symtab, "ip.later_frag", "ip.frag[1]");
166 : 67 : expr_symtab_add_predicate(symtab, "ip.first_frag",
167 : : "ip.is_frag && !ip.later_frag");
168 : :
169 : 67 : expr_symtab_add_predicate(symtab, "arp", "eth.type == 0x806");
170 : 67 : expr_symtab_add_field(symtab, "arp.op", MFF_ARP_OP, "arp", false);
171 : 67 : expr_symtab_add_field(symtab, "arp.spa", MFF_ARP_SPA, "arp", false);
172 : 67 : expr_symtab_add_field(symtab, "arp.sha", MFF_ARP_SHA, "arp", false);
173 : 67 : expr_symtab_add_field(symtab, "arp.tpa", MFF_ARP_TPA, "arp", false);
174 : 67 : expr_symtab_add_field(symtab, "arp.tha", MFF_ARP_THA, "arp", false);
175 : :
176 : 67 : expr_symtab_add_predicate(symtab, "nd",
177 : : "icmp6.type == {135, 136} && icmp6.code == 0 && ip.ttl == 255");
178 : 67 : expr_symtab_add_predicate(symtab, "nd_ns",
179 : : "icmp6.type == 135 && icmp6.code == 0 && ip.ttl == 255");
180 : 67 : expr_symtab_add_predicate(symtab, "nd_na",
181 : : "icmp6.type == 136 && icmp6.code == 0 && ip.ttl == 255");
182 : 67 : expr_symtab_add_field(symtab, "nd.target", MFF_ND_TARGET, "nd", false);
183 : 67 : expr_symtab_add_field(symtab, "nd.sll", MFF_ND_SLL, "nd_ns", false);
184 : 67 : expr_symtab_add_field(symtab, "nd.tll", MFF_ND_TLL, "nd_na", false);
185 : :
186 : 67 : expr_symtab_add_predicate(symtab, "tcp", "ip.proto == 6");
187 : 67 : expr_symtab_add_field(symtab, "tcp.src", MFF_TCP_SRC, "tcp", false);
188 : 67 : expr_symtab_add_field(symtab, "tcp.dst", MFF_TCP_DST, "tcp", false);
189 : 67 : expr_symtab_add_field(symtab, "tcp.flags", MFF_TCP_FLAGS, "tcp", false);
190 : :
191 : 67 : expr_symtab_add_predicate(symtab, "udp", "ip.proto == 17");
192 : 67 : expr_symtab_add_field(symtab, "udp.src", MFF_UDP_SRC, "udp", false);
193 : 67 : expr_symtab_add_field(symtab, "udp.dst", MFF_UDP_DST, "udp", false);
194 : :
195 : 67 : expr_symtab_add_predicate(symtab, "sctp", "ip.proto == 132");
196 : 67 : expr_symtab_add_field(symtab, "sctp.src", MFF_SCTP_SRC, "sctp", false);
197 : 67 : expr_symtab_add_field(symtab, "sctp.dst", MFF_SCTP_DST, "sctp", false);
198 : 67 : }
|