LCOV - code coverage report
Current view: top level - ovn/lib - logical-fields.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 100 101 99.0 %
Date: 2016-09-14 01:02:56 Functions: 2 2 100.0 %
Branches: 15 16 93.8 %

           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 : }

Generated by: LCOV version 1.12