]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd, lib, vtysh: Added support for mac filtering in route-maps
authorMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Wed, 21 Jun 2017 08:02:46 +0000 (01:02 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 8 Aug 2017 14:09:37 +0000 (10:09 -0400)
1. Added support to create mac filters
2. Enabled route-map commands for EVPN address family
3. Provision to add mac filters under match clause in route-maps

Ticket: CM-16349
Review: CCR-6190
Unit-test: Manual (logs attached to ticket)

Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
lib/command.c
lib/command.h
lib/filter.c
lib/prefix.c
lib/prefix.h
vtysh/vtysh_config.c

index e4e421510f2a7905366aff997aae510fd7a69a33..4f2123219114f0d6d0845a1894e581d484100752 100644 (file)
@@ -1584,6 +1584,7 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_info *ri,
 
                info.peer = peer;
                info.attr = attr;
+
                /* don't confuse inbound and outbound setting */
                RESET_FLAG(attr->rmap_change_flags);
 
index 285bb9a80cea2bf5f251a636d6d704d71f21da1d..811ff619a3b78b9184883ab9e85360a1f9b27510 100644 (file)
@@ -54,6 +54,8 @@
 #include "bgpd/bgp_lcommunity.h"
 #include "bgpd/bgp_vty.h"
 #include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_evpn.h"
+#include "bgpd/bgp_evpn_private.h"
 
 #if ENABLE_BGP_VNC
 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
@@ -572,6 +574,52 @@ struct route_map_rule_cmd route_match_ip_route_source_prefix_list_cmd = {
        route_match_ip_route_source_prefix_list_compile,
        route_match_ip_route_source_prefix_list_free};
 
+/* `match mac address MAC_ACCESS_LIST' */
+
+/* Match function should return 1 if match is success else return
+   zero. */
+static route_map_result_t route_match_mac_address(void *rule,
+                                                 struct prefix *prefix,
+                                                 route_map_object_t type,
+                                                 void *object)
+{
+       struct access_list *alist;
+
+       if (type == RMAP_BGP) {
+               alist = access_list_lookup(AFI_L2VPN, (char *)rule);
+               if (alist == NULL)
+                       return RMAP_NOMATCH;
+
+               if (prefix->u.prefix_evpn.route_type != BGP_EVPN_MAC_IP_ROUTE)
+                       return RMAP_NOMATCH;
+
+               return (access_list_apply(alist, &(prefix->u.prefix_evpn.mac))
+                                       == FILTER_DENY
+                               ? RMAP_NOMATCH
+                               : RMAP_MATCH);
+       }
+
+       return RMAP_NOMATCH;
+}
+
+/* Route map `mac address' match statement.  `arg' should be
+   access-list name. */
+static void *route_match_mac_address_compile(const char *arg)
+{
+       return XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg);
+}
+
+/* Free route map's compiled `ip address' value. */
+static void route_match_mac_address_free(void *rule)
+{
+       XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
+}
+
+/* Route map commands for mac address matching. */
+struct route_map_rule_cmd route_match_mac_address_cmd = {
+       "mac address", route_match_mac_address, route_match_mac_address_compile,
+       route_match_mac_address_free};
+
 /* `match local-preference LOCAL-PREF' */
 
 /* Match function return 1 if match is success else return zero. */
@@ -2994,6 +3042,33 @@ static void bgp_route_map_event(route_map_event_t event, const char *rmap_name)
        route_map_notify_dependencies(rmap_name, RMAP_EVENT_MATCH_ADDED);
 }
 
+DEFUN (match_mac_address,
+       match_mac_address_cmd,
+       "match mac address WORD",
+       MATCH_STR
+       "mac address\n"
+       "Match address of route\n"
+       "MAC Access-list name\n")
+{
+       return bgp_route_match_add(vty, "mac address", argv[3]->arg,
+                                  RMAP_EVENT_FILTER_ADDED);
+}
+
+DEFUN (no_match_mac_address,
+       no_match_mac_address_cmd,
+       "no match mac address",
+       NO_STR
+       MATCH_STR
+       "mac\n"
+       "Match address of route\n")
+{
+       if (argc == 0)
+               return bgp_route_match_delete(vty, "mac address", NULL,
+                                             RMAP_EVENT_FILTER_DELETED);
+
+       return bgp_route_match_delete(vty, "mac address", argv[4]->arg,
+                                     RMAP_EVENT_FILTER_DELETED);
+}
 
 DEFUN (match_peer,
        match_peer_cmd,
@@ -4351,6 +4426,7 @@ void bgp_route_map_init(void)
        route_map_install_match(&route_match_probability_cmd);
        route_map_install_match(&route_match_interface_cmd);
        route_map_install_match(&route_match_tag_cmd);
+       route_map_install_match(&route_match_mac_address_cmd);
 
        route_map_install_set(&route_set_ip_nexthop_cmd);
        route_map_install_set(&route_set_local_pref_cmd);
@@ -4381,6 +4457,8 @@ void bgp_route_map_init(void)
        install_element(RMAP_NODE, &no_match_ip_route_source_cmd);
        install_element(RMAP_NODE, &match_ip_route_source_prefix_list_cmd);
        install_element(RMAP_NODE, &no_match_ip_route_source_prefix_list_cmd);
+       install_element(RMAP_NODE, &match_mac_address_cmd);
+       install_element(RMAP_NODE, &no_match_mac_address_cmd);
 
        install_element(RMAP_NODE, &match_aspath_cmd);
        install_element(RMAP_NODE, &no_match_aspath_cmd);
index 0220a7e55de21281169cc73889014e0adcce3c4b..01c27920f5bab3fe863825213d629f49e913b7ba 100644 (file)
@@ -12047,6 +12047,8 @@ void bgp_vty_init(void)
        install_element(BGP_VPNV4_NODE, &no_neighbor_route_map_cmd);
        install_element(BGP_VPNV6_NODE, &neighbor_route_map_cmd);
        install_element(BGP_VPNV6_NODE, &no_neighbor_route_map_cmd);
+       install_element(BGP_EVPN_NODE, &neighbor_route_map_cmd);
+       install_element(BGP_EVPN_NODE, &no_neighbor_route_map_cmd);
 
        /* "neighbor unsuppress-map" commands. */
        install_element(BGP_NODE, &neighbor_unsuppress_map_hidden_cmd);
index f28a55ec6db64fcf277893eb0fd5db6c47db3a38..c25743324aff69ab373822207b433a993a9a570e 100644 (file)
@@ -101,6 +101,7 @@ const char *node_names[] = {
        "ipv4 access list",         // ACCESS_NODE,
        "ipv4 prefix list",         // PREFIX_NODE,
        "ipv6 access list",         // ACCESS_IPV6_NODE,
+       "MAC access list",          // ACCESS_MAC_NODE,
        "ipv6 prefix list",         // PREFIX_IPV6_NODE,
        "as list",                  // AS_LIST_NODE,
        "community list",           // COMMUNITY_LIST_NODE,
index 5184b53a9f6ae4813384e4fefc995259ac393f81..e53b70f7adae7128116e85709b7aec8653069a38 100644 (file)
@@ -123,6 +123,7 @@ enum node_type {
        ACCESS_NODE,            /* Access list node. */
        PREFIX_NODE,            /* Prefix list node. */
        ACCESS_IPV6_NODE,       /* Access list node. */
+       ACCESS_MAC_NODE,        /* MAC access list node*/
        PREFIX_IPV6_NODE,       /* Prefix list node. */
        AS_LIST_NODE,           /* AS list node. */
        COMMUNITY_LIST_NODE,    /* Community list node. */
index 0262234c782596d6ab513ae9f3f3da6cbcc9a4e2..186b32bbbac28455c5bd01d3390628096bccd022 100644 (file)
@@ -90,6 +90,14 @@ struct access_master {
        void (*delete_hook)(struct access_list *);
 };
 
+/* Static structure for IPv4 access_list's master. */
+static struct access_master access_master_mac = {
+       {NULL, NULL},
+       {NULL, NULL},
+       NULL,
+       NULL,
+};
+
 /* Static structure for IPv4 access_list's master. */
 static struct access_master access_master_ipv4 = {
        {NULL, NULL},
@@ -112,6 +120,8 @@ static struct access_master *access_master_get(afi_t afi)
                return &access_master_ipv4;
        else if (afi == AFI_IP6)
                return &access_master_ipv6;
+       else if (afi == AFI_L2VPN)
+               return &access_master_mac;
        return NULL;
 }
 
@@ -146,6 +156,25 @@ static const char *filter_type_str(struct filter *filter)
        }
 }
 
+/*
+ * mac filter match
+ * n is of type struct prefix_eth
+ * p can be of type struct ethaddr
+ */
+static int mac_filter_match(struct prefix *n, struct ethaddr *p)
+{
+       if (!n && !p)
+               return 1;
+
+       if (!n || !p)
+               return 0;
+
+       if (memcmp(&(n->u.prefix), p, sizeof(struct ethaddr)) == 0)
+               return 1;
+
+       return 0;
+}
+
 /* If filter match to the prefix then return 1. */
 static int filter_match_cisco(struct filter *mfilter, struct prefix *p)
 {
@@ -171,22 +200,37 @@ static int filter_match_cisco(struct filter *mfilter, struct prefix *p)
 }
 
 /* If filter match to the prefix then return 1. */
-static int filter_match_zebra(struct filter *mfilter, struct prefix *p)
+static int filter_match_zebra(struct filter *mfilter, void *obj)
 {
-       struct filter_zebra *filter;
+       struct filter_zebra *filter = NULL;
 
        filter = &mfilter->u.zfilter;
 
-       if (filter->prefix.family == p->family) {
-               if (filter->exact) {
-                       if (filter->prefix.prefixlen == p->prefixlen)
+       if (filter->prefix.family == AF_ETHERNET) {
+               struct ethaddr *p = NULL;
+
+               p = (struct ethaddr *)obj;
+               return mac_filter_match(&filter->prefix, p);
+       }
+
+       if (filter->prefix.family == AF_INET
+           || filter->prefix.family == AF_INET6) {
+               struct prefix *p = NULL;
+
+               p = (struct prefix *)obj;
+               if (filter->prefix.family == p->family) {
+                       if (filter->exact) {
+                               if (filter->prefix.prefixlen == p->prefixlen)
+                                       return prefix_match(&filter->prefix, p);
+                               else
+                                       return 0;
+                       } else
                                return prefix_match(&filter->prefix, p);
-                       else
-                               return 0;
                } else
-                       return prefix_match(&filter->prefix, p);
-       } else
-               return 0;
+                       return 0;
+       }
+
+       return 0;
 }
 
 /* Allocate new access list structure. */
@@ -377,7 +421,7 @@ enum filter_type access_list_apply(struct access_list *access, void *object)
                        if (filter_match_cisco(filter, p))
                                return filter->type;
                } else {
-                       if (filter_match_zebra(filter, p))
+                       if (filter_match_zebra(filter, object))
                                return filter->type;
                }
        }
@@ -390,6 +434,7 @@ void access_list_add_hook(void (*func)(struct access_list *access))
 {
        access_master_ipv4.add_hook = func;
        access_master_ipv6.add_hook = func;
+       access_master_mac.add_hook = func;
 }
 
 /* Delete hook function. */
@@ -397,6 +442,7 @@ void access_list_delete_hook(void (*func)(struct access_list *access))
 {
        access_master_ipv4.delete_hook = func;
        access_master_ipv6.delete_hook = func;
+       access_master_mac.delete_hook = func;
 }
 
 /* Add new filter to the end of specified access_list. */
@@ -515,10 +561,18 @@ static struct filter *filter_lookup_zebra(struct access_list *access,
                filter = &mfilter->u.zfilter;
 
                if (filter->exact == new->exact
-                   && mfilter->type
-                              == mnew->type &&prefix_same(&filter->prefix,
-                                                          &new->prefix))
-                       return mfilter;
+                   && mfilter->type == mnew->type) {
+                       if (new->prefix.family == AF_ETHERNET) {
+                               if (prefix_eth_same(
+                                           (struct prefix_eth *)&filter
+                                                   ->prefix,
+                                           (struct prefix_eth *)&new->prefix))
+                                       return mfilter;
+                       } else {
+                               if (prefix_same(&filter->prefix, &new->prefix))
+                                       return mfilter;
+                       }
+               }
        }
        return NULL;
 }
@@ -1252,6 +1306,12 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
                                "IPv6 address prefix/prefixlen is malformed\n");
                        return CMD_WARNING_CONFIG_FAILED;
                }
+       } else if (afi == AFI_L2VPN) {
+               ret = str2prefix_eth(prefix_str, (struct prefix_eth *)&p);
+               if (ret <= 0) {
+                       vty_out(vty, "MAC address is malformed\n");
+                       return CMD_WARNING;
+               }
        } else
                return CMD_WARNING_CONFIG_FAILED;
 
@@ -1274,7 +1334,6 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
                        access_list_filter_add(access, mfilter);
        } else {
                struct filter *delete_filter;
-
                delete_filter = filter_lookup_zebra(access, mfilter);
                if (delete_filter)
                        access_list_filter_delete(access, delete_filter);
@@ -1285,6 +1344,64 @@ static int filter_set_zebra(struct vty *vty, const char *name_str,
        return CMD_SUCCESS;
 }
 
+DEFUN (mac_access_list,
+       mac_access_list_cmd,
+       "mac access-list WORD <deny|permit> MAC",
+       "Add a mac access-list\n"
+       "Add an access list entry\n"
+       "MAC zebra access-list name\n"
+       "Specify packets to reject\n"
+       "Specify packets to forward\n"
+       "MAC address to match. e.g. 00:01:00:01:00:01\n")
+{
+       return filter_set_zebra(vty, argv[2]->arg, argv[3]->arg, AFI_L2VPN,
+                               argv[4]->arg, 0, 1);
+}
+
+DEFUN (no_mac_access_list,
+       no_mac_access_list_cmd,
+       "no mac access-list WORD <deny|permit> MAC",
+       NO_STR
+       "Remove a mac access-list\n"
+       "Remove an access list entry\n"
+       "MAC zebra access-list name\n"
+       "Specify packets to reject\n"
+       "Specify packets to forward\n"
+       "MAC address to match. e.g. 00:01:00:01:00:01\n")
+{
+       return filter_set_zebra(vty, argv[3]->arg, argv[4]->arg, AFI_L2VPN,
+                               argv[5]->arg, 0, 0);
+}
+
+DEFUN (mac_access_list_any,
+       mac_access_list_any_cmd,
+       "mac access-list WORD <deny|permit> any",
+       "Add a mac access-list\n"
+       "Add an access list entry\n"
+       "MAC zebra access-list name\n"
+       "Specify packets to reject\n"
+       "Specify packets to forward\n"
+       "MAC address to match. e.g. 00:01:00:01:00:01\n")
+{
+       return filter_set_zebra(vty, argv[2]->arg, argv[3]->arg, AFI_L2VPN,
+                               "00:00:00:00:00:00", 0, 1);
+}
+
+DEFUN (no_mac_access_list_any,
+       no_mac_access_list_any_cmd,
+       "no mac access-list WORD <deny|permit> any",
+       NO_STR
+       "Remove a mac access-list\n"
+       "Remove an access list entry\n"
+       "MAC zebra access-list name\n"
+       "Specify packets to reject\n"
+       "Specify packets to forward\n"
+       "MAC address to match. e.g. 00:01:00:01:00:01\n")
+{
+       return filter_set_zebra(vty, argv[2]->arg, argv[3]->arg, AFI_L2VPN,
+                               "00:00:00:00:00:00", 0, 0);
+}
+
 DEFUN (access_list_exact,
        access_list_exact_cmd,
        "access-list WORD <deny|permit> A.B.C.D/M [exact-match]",
@@ -1666,12 +1783,15 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
                        filter = &mfilter->u.cfilter;
 
                        if (write) {
-                               vty_out(vty, "%s IP%s access list %s\n",
+                               vty_out(vty, "%s %s access list %s\n",
                                        mfilter->cisco ? (filter->extended
                                                                  ? "Extended"
                                                                  : "Standard")
                                                       : "Zebra",
-                                       afi == AFI_IP6 ? "v6" : "",
+                                       (afi == AFI_IP)
+                                               ? ("")
+                                               : ((afi == AFI_IP6) ? ("ipv6 ")
+                                                                   : ("mac ")),
                                        access->name);
                                write = 0;
                        }
@@ -1710,12 +1830,15 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
                        filter = &mfilter->u.cfilter;
 
                        if (write) {
-                               vty_out(vty, "%s IP%s access list %s\n",
+                               vty_out(vty, "%s %s access list %s\n",
                                        mfilter->cisco ? (filter->extended
                                                                  ? "Extended"
                                                                  : "Standard")
                                                       : "Zebra",
-                                       afi == AFI_IP6 ? "v6" : "",
+                                       (afi == AFI_IP)
+                                               ? ("")
+                                               : ((afi == AFI_IP6) ? ("ipv6 ")
+                                                                   : ("mac ")),
                                        access->name);
                                write = 0;
                        }
@@ -1746,6 +1869,29 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
        return CMD_SUCCESS;
 }
 
+/* show MAC access list - this only has MAC filters for now*/
+DEFUN (show_mac_access_list,
+       show_mac_access_list_cmd,
+       "show mac access-list",
+       SHOW_STR
+       "mac access lists\n"
+       "List mac access lists\n")
+{
+       return filter_show(vty, NULL, AFI_L2VPN);
+}
+
+DEFUN (show_mac_access_list_name,
+       show_mac_access_list_name_cmd,
+       "show mac access-list WORD",
+       SHOW_STR
+       "mac\n"
+       "List mac access lists\n"
+       "mac zebra access-list\n"
+       "mac address")
+{
+       return filter_show(vty, argv[3]->arg, AFI_L2VPN);
+}
+
 DEFUN (show_ip_access_list,
        show_ip_access_list_cmd,
        "show ip access-list",
@@ -1844,10 +1990,13 @@ void config_write_access_zebra(struct vty *vty, struct filter *mfilter)
 
        if (p->prefixlen == 0 && !filter->exact)
                vty_out(vty, " any");
-       else
+       else if (p->family == AF_INET6 || p->family == AF_INET)
                vty_out(vty, " %s/%d%s",
                        inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
                        p->prefixlen, filter->exact ? " exact-match" : "");
+       else
+               vty_out(vty, " %s",
+                       prefix_mac2str(&(p->u.prefix_eth), buf, sizeof(buf)));
 
        vty_out(vty, "\n");
 }
@@ -1866,15 +2015,19 @@ static int config_write_access(struct vty *vty, afi_t afi)
        for (access = master->num.head; access; access = access->next) {
                if (access->remark) {
                        vty_out(vty, "%saccess-list %s remark %s\n",
-                               afi == AFI_IP ? "" : "ipv6 ", access->name,
-                               access->remark);
+                               (afi == AFI_IP) ? ("")
+                                               : ((afi == AFI_IP6) ? ("ipv6 ")
+                                                                   : ("mac ")),
+                               access->name, access->remark);
                        write++;
                }
 
                for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
                        vty_out(vty, "%saccess-list %s %s",
-                               afi == AFI_IP ? "" : "ipv6 ", access->name,
-                               filter_type_str(mfilter));
+                               (afi == AFI_IP) ? ("")
+                                               : ((afi == AFI_IP6) ? ("ipv6 ")
+                                                                   : ("mac ")),
+                               access->name, filter_type_str(mfilter));
 
                        if (mfilter->cisco)
                                config_write_access_cisco(vty, mfilter);
@@ -1888,15 +2041,19 @@ static int config_write_access(struct vty *vty, afi_t afi)
        for (access = master->str.head; access; access = access->next) {
                if (access->remark) {
                        vty_out(vty, "%saccess-list %s remark %s\n",
-                               afi == AFI_IP ? "" : "ipv6 ", access->name,
-                               access->remark);
+                               (afi == AFI_IP) ? ("")
+                                               : ((afi == AFI_IP6) ? ("ipv6 ")
+                                                                   : ("mac ")),
+                               access->name, access->remark);
                        write++;
                }
 
                for (mfilter = access->head; mfilter; mfilter = mfilter->next) {
                        vty_out(vty, "%saccess-list %s %s",
-                               afi == AFI_IP ? "" : "ipv6 ", access->name,
-                               filter_type_str(mfilter));
+                               (afi == AFI_IP) ? ("")
+                                               : ((afi == AFI_IP6) ? ("ipv6 ")
+                                                                   : ("mac ")),
+                               access->name, filter_type_str(mfilter));
 
                        if (mfilter->cisco)
                                config_write_access_cisco(vty, mfilter);
@@ -1909,6 +2066,56 @@ static int config_write_access(struct vty *vty, afi_t afi)
        return write;
 }
 
+static struct cmd_node access_mac_node = {
+       ACCESS_MAC_NODE, "", /* Access list has no interface. */
+       1};
+
+static int config_write_access_mac(struct vty *vty)
+{
+       return config_write_access(vty, AFI_L2VPN);
+}
+
+static void access_list_reset_mac(void)
+{
+       struct access_list *access;
+       struct access_list *next;
+       struct access_master *master;
+
+       master = access_master_get(AFI_L2VPN);
+       if (master == NULL)
+               return;
+
+       for (access = master->num.head; access; access = next) {
+               next = access->next;
+               access_list_delete(access);
+       }
+       for (access = master->str.head; access; access = next) {
+               next = access->next;
+               access_list_delete(access);
+       }
+
+       assert(master->num.head == NULL);
+       assert(master->num.tail == NULL);
+
+       assert(master->str.head == NULL);
+       assert(master->str.tail == NULL);
+}
+
+/* Install vty related command. */
+static void access_list_init_mac(void)
+{
+       install_node(&access_mac_node, config_write_access_mac);
+
+       install_element(ENABLE_NODE, &show_mac_access_list_cmd);
+       install_element(ENABLE_NODE, &show_mac_access_list_name_cmd);
+
+       /* Zebra access-list */
+       install_element(CONFIG_NODE, &mac_access_list_cmd);
+       install_element(CONFIG_NODE, &no_mac_access_list_cmd);
+       install_element(CONFIG_NODE, &mac_access_list_any_cmd);
+       install_element(CONFIG_NODE, &no_mac_access_list_any_cmd);
+}
+
 /* Access-list node. */
 static struct cmd_node access_node = {ACCESS_NODE,
                                      "", /* Access list has no interface. */
@@ -2050,10 +2257,12 @@ void access_list_init()
 {
        access_list_init_ipv4();
        access_list_init_ipv6();
+       access_list_init_mac();
 }
 
 void access_list_reset()
 {
        access_list_reset_ipv4();
        access_list_reset_ipv6();
+       access_list_reset_mac();
 }
index 33b6ff198776f0b39a4b7ffce6d12b9d4f0f1171..e67184f52b04719ef6a48bd57a03218d70269785 100644 (file)
@@ -37,390 +37,262 @@ static const u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
 static const struct in6_addr maskbytes6[] = {
        /* /0   */ {{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /1   */
-       {{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /2   */
-       {{{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /3   */
-       {{{0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /4   */
-       {{{0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /5   */
-       {{{0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /6   */
-       {{{0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /7   */
-       {{{0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /8   */
-       {{{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /9   */
-       {{{0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /10  */
-       {{{0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /11  */
-       {{{0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /12  */
-       {{{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /13  */
-       {{{0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /14  */
-       {{{0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /15  */
-       {{{0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /16  */
-       {{{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /17  */
-       {{{0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /18  */
-       {{{0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /19  */
-       {{{0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /20  */
-       {{{0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /21  */
-       {{{0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /22  */
-       {{{0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /23  */
-       {{{0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /24  */
-       {{{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /25  */
-       {{{0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /26  */
-       {{{0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /27  */
-       {{{0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /28  */
-       {{{0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /29  */
-       {{{0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /30  */
-       {{{0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /31  */
-       {{{0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /32  */
-       {{{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /33  */
-       {{{0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /34  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /35  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /36  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /37  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /38  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /39  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /40  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /41  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /42  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /43  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /44  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /45  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /46  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /47  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /48  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /49  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /50  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /51  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /52  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /53  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /54  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /55  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /56  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /57  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /58  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /59  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /60  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /61  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /62  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /63  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /64  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /65  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /66  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /67  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /68  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /69  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /70  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /71  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /72  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /73  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /74  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /75  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /76  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /77  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /78  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /79  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /80  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /81  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /82  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /83  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /84  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /85  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /86  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /87  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /88  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0x00, 0x00, 0x00, 0x00, 0x00}}},
-       /* /89  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0x80, 0x00, 0x00, 0x00, 0x00}}},
-       /* /90  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xc0, 0x00, 0x00, 0x00, 0x00}}},
-       /* /91  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xe0, 0x00, 0x00, 0x00, 0x00}}},
-       /* /92  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xf0, 0x00, 0x00, 0x00, 0x00}}},
-       /* /93  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xf8, 0x00, 0x00, 0x00, 0x00}}},
-       /* /94  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xfc, 0x00, 0x00, 0x00, 0x00}}},
-       /* /95  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xfe, 0x00, 0x00, 0x00, 0x00}}},
-       /* /96  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0x00, 0x00, 0x00, 0x00}}},
-       /* /97  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0x80, 0x00, 0x00, 0x00}}},
-       /* /98  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xc0, 0x00, 0x00, 0x00}}},
-       /* /99  */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xe0, 0x00, 0x00, 0x00}}},
-       /* /100 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xf0, 0x00, 0x00, 0x00}}},
-       /* /101 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xf8, 0x00, 0x00, 0x00}}},
-       /* /102 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xfc, 0x00, 0x00, 0x00}}},
-       /* /103 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xfe, 0x00, 0x00, 0x00}}},
-       /* /104 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0x00, 0x00, 0x00}}},
-       /* /105 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0x80, 0x00, 0x00}}},
-       /* /106 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xc0, 0x00, 0x00}}},
-       /* /107 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xe0, 0x00, 0x00}}},
-       /* /108 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xf0, 0x00, 0x00}}},
-       /* /109 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xf8, 0x00, 0x00}}},
-       /* /110 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xfc, 0x00, 0x00}}},
-       /* /111 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xfe, 0x00, 0x00}}},
-       /* /112 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0x00, 0x00}}},
-       /* /113 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0x80, 0x00}}},
-       /* /114 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xc0, 0x00}}},
-       /* /115 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xe0, 0x00}}},
-       /* /116 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xf0, 0x00}}},
-       /* /117 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xf8, 0x00}}},
-       /* /118 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xfc, 0x00}}},
-       /* /119 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xfe, 0x00}}},
-       /* /120 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0x00}}},
-       /* /121 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0x80}}},
-       /* /122 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0xc0}}},
-       /* /123 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0xe0}}},
-       /* /124 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0xf0}}},
-       /* /125 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0xf8}}},
-       /* /126 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0xfc}}},
-       /* /127 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0xfe}}},
-       /* /128 */
-       {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-          0xff, 0xff, 0xff, 0xff, 0xff}}}};
+       /* /1   */ {{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /2   */ {{{0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /3   */ {{{0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /4   */ {{{0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /5   */ {{{0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /6   */ {{{0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /7   */ {{{0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /8   */ {{{0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /9   */ {{{0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /10  */ {{{0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /11  */ {{{0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /12  */ {{{0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /13  */ {{{0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /14  */ {{{0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /15  */ {{{0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /16  */ {{{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /17  */ {{{0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /18  */ {{{0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /19  */ {{{0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /20  */ {{{0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /21  */ {{{0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /22  */ {{{0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /23  */ {{{0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /24  */ {{{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /25  */ {{{0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /26  */ {{{0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /27  */ {{{0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /28  */ {{{0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /29  */ {{{0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /30  */ {{{0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /31  */ {{{0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /32  */ {{{0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /33  */ {{{0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /34  */ {{{0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /35  */ {{{0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /36  */ {{{0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /37  */ {{{0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /38  */ {{{0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /39  */ {{{0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /40  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /41  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /42  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /43  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /44  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /45  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /46  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /47  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /48  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /49  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /50  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /51  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /52  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /53  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /54  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /55  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /56  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /57  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /58  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /59  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /60  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /61  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /62  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /63  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /64  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /65  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /66  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /67  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /68  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /69  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /70  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /71  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /72  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /73  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /74  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /75  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /76  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /77  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /78  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /79  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /80  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /81  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /82  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /83  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /84  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /85  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /86  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /87  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /88  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}}},
+       /* /89  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00}}},
+       /* /90  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00}}},
+       /* /91  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00}}},
+       /* /92  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00}}},
+       /* /93  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00}}},
+       /* /94  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00}}},
+       /* /95  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00}}},
+       /* /96  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00}}},
+       /* /97  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00}}},
+       /* /98  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00}}},
+       /* /99  */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00}}},
+       /* /100 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00}}},
+       /* /101 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00}}},
+       /* /102 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00}}},
+       /* /103 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00}}},
+       /* /104 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00}}},
+       /* /105 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0x80, 0x00, 0x00}}},
+       /* /106 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xc0, 0x00, 0x00}}},
+       /* /107 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00}}},
+       /* /108 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xf0, 0x00, 0x00}}},
+       /* /109 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xf8, 0x00, 0x00}}},
+       /* /110 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00}}},
+       /* /111 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00}}},
+       /* /112 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00}}},
+       /* /113 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00}}},
+       /* /114 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00}}},
+       /* /115 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00}}},
+       /* /116 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0x00}}},
+       /* /117 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x00}}},
+       /* /118 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00}}},
+       /* /119 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x00}}},
+       /* /120 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00}}},
+       /* /121 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80}}},
+       /* /122 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0}}},
+       /* /123 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0}}},
+       /* /124 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0}}},
+       /* /125 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8}}},
+       /* /126 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}}},
+       /* /127 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}}},
+       /* /128 */ {{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+                     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}}};
 
 /* Number of bits in prefix type. */
 #ifndef PNBBY
@@ -589,6 +461,24 @@ void prefix_copy(struct prefix *dest, const struct prefix *src)
        }
 }
 
+/* check if the two prefix_eth struct are same*/
+int prefix_eth_same(struct prefix_eth *p1, struct prefix_eth *p2)
+{
+       if (!p1 && !p2)
+               return 1;
+
+       if (p1 && !p2)
+               return 0;
+
+       if (!p1 && p2)
+               return 0;
+
+       if (memcmp(p1, p2, sizeof(struct prefix_eth)) == 0)
+               return 1;
+
+       return 0;
+}
+
 /*
  * Return 1 if the address/netmask contained in the prefix structure
  * is the same, and else return 0.  For this routine, 'same' requires
index 5f2b57ccce2613aba71ec00bb360c894bc036931..0f3ad562d9a2ea292fe2f895af1e4ed72a72a07a 100644 (file)
@@ -293,6 +293,7 @@ extern int prefix_cmp(const struct prefix *, const struct prefix *);
 extern int prefix_common_bits(const struct prefix *, const struct prefix *);
 extern void prefix_copy(struct prefix *dest, const struct prefix *src);
 extern void apply_mask(struct prefix *);
+extern int prefix_eth_same(struct prefix_eth *p1, struct prefix_eth *p2);
 
 extern struct prefix *sockunion2prefix(const union sockunion *dest,
                                       const union sockunion *mask);
@@ -356,6 +357,7 @@ static inline int ipv6_martian(struct in6_addr *addr)
 }
 
 extern int all_digit(const char *);
+extern int macstr2prefix_evpn(const char *str, struct prefix_evpn *p);
 
 /* NOTE: This routine expects the address argument in network byte order. */
 static inline int ipv4_martian(struct in_addr *addr)
index 74509d1ec81cd4fa9720c097609830ced0f0e9b8..d388b568ad7ed36ff56b08852e5ac2c21fd6a9d1 100644 (file)
@@ -222,6 +222,10 @@ void vtysh_config_parse_line(void *arg, const char *line)
                                 strlen("ipv6 access-list"))
                         == 0)
                        config = config_get(ACCESS_IPV6_NODE, line);
+               else if (strncmp(line, "mac access-list",
+                                strlen("mac access-list"))
+                        == 0)
+                       config = config_get(ACCESS_MAC_NODE, line);
                else if (strncmp(line, "ip prefix-list",
                                 strlen("ip prefix-list"))
                         == 0)
@@ -300,9 +304,10 @@ void vtysh_config_parse_line(void *arg, const char *line)
 #define NO_DELIMITER(I)                                                        \
        ((I) == ACCESS_NODE || (I) == PREFIX_NODE || (I) == IP_NODE            \
         || (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE                  \
-        || (I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE                 \
-        || (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \
-        || (I) == AAA_NODE || (I) == VRF_DEBUG_NODE || (I) == MPLS_NODE)
+        || (I) == ACCESS_IPV6_NODE || (I) == ACCESS_MAC_NODE                  \
+        || (I) == PREFIX_IPV6_NODE || (I) == SERVICE_NODE                     \
+        || (I) == FORWARDING_NODE || (I) == DEBUG_NODE || (I) == AAA_NODE     \
+        || (I) == VRF_DEBUG_NODE || (I) == MPLS_NODE)
 
 /* Display configuration to file pointer. */
 void vtysh_config_dump(FILE *fp)