OpenNSL API Guide and Reference Manual
example_vxlan.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * (C) Copyright Broadcom Corporation 2017
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  ******************************************************************************
18  * \file example_vxlan.c
19  *
20  * \brief Example code for VxLAN application
21  *
22  * VXLAN is a L2 VPN technology targeted for Data-Center communication
23  * between Virtual Machines (VM) assigned to the same customer(Tenant) that are
24  * distributed in various racks in the Data-Center. L2VPN over IP/UDP tunnels can provide
25  * E-LAN (similar to VPLS) and E-LINE (similar to VPWS) service. With VXLAN the ethernet
26  * packets are encapsulated in UDP tunnels over an IP network. VXLAN uses UDP Source_Port
27  * as multiplexing field for multiplexing multiple VPNs into the same UDP Tunnel.
28  * E-LINE is point-to-point service without support for Multicast traffic. In E-LINE, Ethernet
29  * frames are mapped into a VXLAN Tunnel based on incoming port plus packet header information.
30  * At the end of Tunnel, forwarding of Ethernet frames after Tunnel decapsulation is based on
31  * VXLAN-VNID and Tunnel lookup.
32  *
33  * In E-LAN, Ethernet frames of interest are also identified by incoming port plus packet
34  * header information. Ethernet frames are switched into one or more VXLAN Tunnels based
35  * on the MAC DA lookup. At the end of Tunnel, forwarding of Ethernet frames after Tunnel
36  * decapsulation is based on the VXLAN-VNID and Tunnel lookup and frames are again forwarded
37  * based on MAC-DA lookup.
38  *
39  * VXLAN VPN can be of type ELINE or ELAN.
40  *
41  * For ELAN, a VPN is similar to a VLAN, which identifies a group of physical ports to be
42  * included in a broadcast domain. However, instead of physical ports, a ELAN VPN identifies
43  * a group of "virtual-ports" to be included in a broadcast domain. In the VXLAN APIs,
44  * a "virtual-port" is called an VXLAN port (see description below). The VPN ID is used to
45  * qualify MAC DA lookups within the VPN.
46  *
47  * For ELINE, a VPN consists of two VXLAN ports. Packets arriving on one VXLAN port are sent
48  * directly out the other VXLAN port.
49  *
50  * This example application creates a VxLAN segment:
51  *
52  * VM1 --- Access Port --> Segment (VPN) -> network UDP tunnel --- VM2
53  *
54  * Setup configuration:
55  * The following configuration needs to provided using platform configuration file (opennsl.cfg)
56  * to run the VxLAN the application.
57  * bcm886xx_ip4_tunnel_termination_mode=0
58  * bcm886xx_l2gre_enable=0
59  * bcm886xx_vxlan_enable=1
60  * bcm886xx_ether_ip_enable=0
61  * bcm886xx_vxlan_tunnel_lookup_mode=2
62  * split_horizon_forwarding_groups_mode=1
63  *
64  * Testing Description:
65  * Packet from Access Port to Network Port (Packet encapsulation):
66  * A packet sent from access port with parameters: Access VLAN = 200, SMAC = VM1 MAC,
67  * DMAC = VM2 MAC will be received on networking port with VxLAN encapsulation as follows:
68  * SMAC = Switch MAC (00:0c:00:02:00:00), DMAC = Nexthop MAC (20:00:00:00:cd:1d)
69  *
70  * Packet from Network Port to Access Port (Packet decapsulation):
71  * A packet sent from network port with parameters: Tunnel VLAN = 20, SMAC = Router MAC
72 * (20:00:00:00:cd:1d), DMAC = Switch MAC (00:0c:00:02:00:00), Destination UDP Port = 4789
73  * will be received on access port as follows:
74  * SMAC = VM2 MAC, DMAC = VM1 MAC
75  *
76  ******************************************************************************/
77 
78 #include <stdio.h>
79 #include <stdlib.h>
80 #include <string.h>
81 #include <sal/driver.h>
82 #include <opennsl/error.h>
83 #include <opennsl/init.h>
84 #include <opennsl/l2.h>
85 #include <opennsl/switch.h>
86 #include <opennsl/vlan.h>
87 #include <opennsl/vswitch.h>
88 #include <opennsl/tunnel.h>
89 #include <opennsl/multicast.h>
90 #include <opennsl/vxlan.h>
91 #include <examples/util.h>
92 
93 #define DEFAULT_UNIT 0
94 
95 char example_usage[] =
96 "Syntax: example_vxlan \n\r"
97 " \n\r"
98 "Paramaters: None. \n\r"
99 " \n\r"
100 "Usage Guidelines: None. \n\r";
101 
102 /* Global Variables */
103 int verbose = 0; /* To enable debug prints */
104 int egress_mc = 0;
107 
108 /* Configure vxlan port */
110  /* INPUT */
111  uint32 vpn; /* vpn to which we add the vxlan port */
112  opennsl_gport_t in_port; /* network side port for learning info. */
113  opennsl_gport_t in_tunnel; /* ip tunnel terminator gport */
114  opennsl_gport_t out_tunnel; /* ip tunnel initiator gport */
115  opennsl_if_t egress_if; /* FEC entry, contains ip tunnel encapsulation information */
116  uint32 flags; /* vxlan flags */
117  int set_egress_orientation_using_vxlan_port_add; /* egress orientation can be configured:
118  - using the api opennsl_vxlan_port_add,
119  when egress_tunnel_id (ip tunnel initiator gport, contains outlif) is valid (optional).
120  - using the api opennsl_port_class_set, update egress orientation.
121  By default: enabled */
122  int network_group_id; /* forwarding group for vxlan port. Used for orientation filter */
123 
124  /* If the FEC that is passed to vxlan port is an ECMP. We can't add directly the vxlan port to the
125  * VSI flooding MC group.
126  * We'll add instead the tunnel initiator interface to the VSI flooding MC group */
127  int is_ecmp; /* indicate that FEC that is passed to vxlan port is an ECMP */
128  opennsl_if_t out_tunnel_if; /* ip tunnel initiator itf */
129 
130  /* OUTPUT */
131  opennsl_gport_t vxlan_port_id; /* returned vxlan gport */
132 };
133 /* __doxy_func_body_end__ */
134 
135 /* Creating L3 interface */
137  /* Input */
138  uint32 flags; /* OPENNSL_L3_XXX */
139  uint32 ingress_flags; /* OPENNSL_L3_INGRESS_XXX */
140  int no_publc; /* Used to force no public, public is forced if vrf = 0 or scale feature is turned on */
141  int vsi;
144  int vrf_valid; /* Do we need to set vrf */
145  int vrf;
146  int rpf_valid; /* Do we need to set rpf */
147  opennsl_l3_ingress_urpf_mode_t urpf_mode; /* avail. when OPENNSL_L3_RPF is set */
149  int mtu;
154  int ttl;
156 
157  /* Output */
158  int rif;
159  uint8 skip_mymac; /* If true, mymac will not be set. Make sure you set it elsewhere. */
160 };
161 /* __doxy_func_body_end__ */
162 
163 /* Creating L3 egress */
165  /* Input */
166  uint32 allocation_flags; /* OPENNSL_L3_XXX */
167  uint32 l3_flags; /* OPENNSL_L3_XXX */
168  uint32 l3_flags2; /* OPENNSL_L3_FLAGS2_XXX */
169 
170  /* ARP */
171  int vlan; /* Outgoing vlan-VSI, relevant for ARP creation. In case set then SA MAC address is retreived from this VSI. */
172  opennsl_mac_t next_hop_mac_addr; /* Next-hop MAC address, relevant for ARP creation */
173  int qos_map_id; /* General QOS map id */
174 
175  /* FEC */
176  opennsl_if_t out_tunnel_or_rif; /* *Outgoing intf, can be tunnel/rif, relevant for FEC creation */
177  opennsl_gport_t out_gport; /* *Outgoing port , relevant for FEC creation */
178 
179  /* Input/Output ID allocation */
180  opennsl_if_t fec_id; /* *FEC ID */
181  opennsl_if_t arp_encap_id; /* *ARP ID, may need for allocation ID or for FEC creation */
182 };
183 /* __doxy_func_body_end__ */
184 
185 struct vxlan_s {
186  int vpn_id;
187  int vni;
188  int vxlan_vdc_enable; /* Option to enable/disable VXLAN VDC support */
189  int vxlan_network_group_id; /* ingress and egress orientation for VXLAN */
190  int dip_sip_vrf_using_my_vtep_index_mode; /* configure DIP-> my-vtep-index, tunnel term: my-vtep-index, SIP, VRF and
191  default tunnel term: DIP, SIP, VRF */
192  int my_vtep_index; /* used in dip_sip_vrf_using_my_vtep_index_mode */
193  int access_port; /* access port for the script */
194  int network_port; /* Network port for the script */
195  /* HW object created by the script */
196  opennsl_gport_t tunnel_init_gport; /* GPORT for Tunnel initiator */
197  opennsl_if_t tunnel_init_intf_id; /* Tunnel interface Id for vxlan Tunnel */
198  opennsl_if_t vxlan_fec_intf_id; /* fec for the VXLAN tunnel, set at example_vxlan */
199  int mc_group_id; /* Flood group created for VPN */
200  opennsl_gport_t tunnel_term_gport; /* GPORT for tunnel terminator */
201  opennsl_if_t prov_vlan_l3_intf_id; /* L3 interface on provider vlan */
202  opennsl_gport_t vlan_inLif; /* InLif for the VLAN port on access port */
203  opennsl_gport_t vxlan_gport; /* GPORT for the VXLAN */
204  opennsl_mac_t user_mac_address; /* UC static MAC address for inLif */
205  opennsl_mac_t tunnel_mac_address; /* UC static MAC address for VxLAN */
206  opennsl_mac_t mc_mac; /* reserved MAC for MC traffic */
207 };
208 /* __doxy_func_body_end__ */
209 
210 struct vxlan_s g_vxlan = {
211  15, /* vpn_id */
212  5000, /* vni */
213  0, /* enable vdc support */
214  1, /* vxlan orientation */
215  0, /* dip_sip_vrf_using_my_vtep_index_mode */
216  0x2, /* my_vtep_index */
217  0, /* access port: Updated by script on execution */
218  0, /* network port: Updated by script on execution */
219  0,0,0,0,0,0,0,0, /* Updatedd by script on execution */
220  { 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0 },
221  { 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1 },
222  { 0x01, 0x00, 0x5E, 0x01, 0x01, 0x14 }
223 };
224 /* __doxy_func_body_end__ */
225 
227 #define MY_MAC {0x00, 0x0c, 0x00, 0x02, 0x00, 0x00}
228 /* __doxy_func_body_end__ */
229 
230 struct ip_tunnel_s {
231  opennsl_mac_t da; /* ip tunnel da */
232  opennsl_mac_t sa; /* ip tunnel my mac */
233  int sip; /* ip tunnel sip */
234  int sip_mask;
235  int dip; /* ip tunnel dip */
236  int dip_mask;
237  int ttl; /* ip tunnel ttl */
238  int dscp; /* ip tunnel dscp */
239  opennsl_tunnel_dscp_select_t dscp_sel; /* ip tunnel dscp_sel */
240  int flags;
241 };
242 /* __doxy_func_body_end__ */
243 
244 /*
245  * struct include meta information.
246  * where the cint logic pull data from this struct.
247  * use to control differ runs of the cint, without changing the cint code
248  */
252  int tunnel_vlan; /* vlan for ip tunnels */
255 };
256 /* __doxy_func_body_end__ */
257 
259  /* tunnel type */
261  /* tunnel da | sa | sip: 170.0.0.17 | mask:0 */
262  {{0x20, 0x00, 0x00, 0x00, 0xcd, 0x1d}, MY_MAC, 0xAA000011, 0,
263  0xAB000011, 0xFFFFFFFF, 50, 11, opennslTunnelDscpPacket, OPENNSL_TUNNEL_INIT_USE_INNER_DF},
264  /* vlan for both ip tunnels */
265  20,
266  20,
267  200
268 };
269 /* __doxy_func_body_end__ */
270 
271 int example_ip_tunnel_add(int unit, opennsl_if_t *itf,
273 
274 /* Utility API */
275 int portmap[100] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
276 /* __doxy_func_body_end__ */
277 /*****************************************************************/
284 void init_portmap(int unit)
285 {
286  opennsl_info_t info;
287  int rv = opennsl_info_get(unit, &info);
288  if (rv != OPENNSL_E_NONE) {
289  printf("Error in getting the chip info, Error = %s\n", opennsl_errmsg(rv));
290  return;
291  }
292 
293  if (example_is_qmx_device(unit))
294  {
295  portmap[1]=13; portmap[2]=14; portmap[3]=15; portmap[4]=16;
296  portmap[5]=17; portmap[6]=18; portmap[7]=19; portmap[8]=20;
297  portmap[9]=21; portmap[10]=22; portmap[11]=23; portmap[12]=24;
298  portmap[13]=25; portmap[14]=26; portmap[15]=27; portmap[16]=28;
299  portmap[17]=29; portmap[18]=30; portmap[19]=31; portmap[20]=32;
300  }
301  else
302  {
303  printf("device is not QMX\n");
304  int i;
305  for (i=1;i<50;i++)
306  portmap[i]=i;
307 
308  }
309 }
310 /* __doxy_func_body_end__ */
311 
312 /*****************************************************************/
321  opennsl_tunnel_terminator_t *tunnel_term)
322 {
323  printf("%s key: ", type);
324 
325  if (tunnel_term->sip_mask == 0) {
326  printf("SIP: masked ");
327  } else if (tunnel_term->sip_mask == 0xFFFFFFFF) {
328  print_ip_addr("SIP:", tunnel_term->sip);
329  printf("/0x%08x ", tunnel_term->sip_mask);
330  }
331  if (tunnel_term->dip_mask == 0) {
332  printf("DIP: masked ");
333  } else if (tunnel_term->dip_mask == 0xFFFFFFFF) {
334  print_ip_addr("DIP:", tunnel_term->dip);
335  printf("/0x%08x ", tunnel_term->dip_mask);
336  }
337 
338  printf("RIF: 0x%08x ", tunnel_term->tunnel_if);
339 
340  printf("\n\r");
341 }
342 /* __doxy_func_body_end__ */
343 
344 
345 /*
346  * add entry to mac table <vlan,mac> --> port
347  * <VID, MAC> --> port
348  */
349 /*****************************************************************/
361 {
362 
363  int rv;
364 
365  opennsl_l2_addr_t l2addr;
366 
367  opennsl_l2_addr_t_init(&l2addr, mac, vid);
368 
369  l2addr.port = port;
370  l2addr.vid = vid;
371  l2addr.flags = OPENNSL_L2_STATIC;
372 
373  rv = opennsl_l2_addr_add(unit, &l2addr);
374  if (rv != OPENNSL_E_NONE) {
375  printf("Error, Failed to add L2 entry, Error %s\n", opennsl_errmsg(rv));
376  return rv;
377  }
378 
379  if (verbose > 2) {
380  printf("l2 entry: fid = %d ", vid);
381  l2_print_mac("mac =", mac);
382  printf(" dest-port 0x%08x \n", port);
383  }
384  return OPENNSL_E_NONE;
385 }
386 /* __doxy_func_body_end__ */
387 
388 
389 /*****************************************************************/
401 int example_add_multicast_entry(int unit, int ipmc_index,
402  int *ports, int *cud, int nof_mc_entries, int is_egress)
403 {
404  int rv = OPENNSL_E_NONE;
405  int i;
406 
407  for (i = 0; i < nof_mc_entries; i++) {
408  /* egress MC */
409  if (is_egress) {
410  rv = opennsl_multicast_egress_add(unit, ipmc_index, ports[i], cud[i]);
411  if (rv != OPENNSL_E_NONE) {
412  printf("Failed to add egress multicast entry, port %d encap_id: %d, Error %s\n", ports[i],
413  cud[i], opennsl_errmsg(rv));
414  return rv;
415  }
416  }
417  /* ingress MC */
418  else {
419  rv = opennsl_multicast_ingress_add(unit, ipmc_index, ports[i], cud[i]);
420  if (rv != OPENNSL_E_NONE) {
421  printf("Error, opennsl_multicast_ingress_add: port %d encap_id: %d \n",
422  ports[i], cud[i]);
423  return rv;
424  }
425  }
426  }
427 
428  return rv;
429 }
430 /* __doxy_func_body_end__ */
431 
432 /*****************************************************************/
443 int example_vlan_port_add( int unit, int mc_group_id,
444  int sys_port, int gport, uint8 is_egress)
445 {
446  int encap_id;
447  int rv;
448 
449  rv = opennsl_multicast_vlan_encap_get(unit, mc_group_id, sys_port, gport, &encap_id);
450  if (rv != OPENNSL_E_NONE) {
451  printf("Failed to get multicast encapsulation ID for Multicast group 0x%08x"
452  " phy_port: 0x%08x gport: 0x%08x, Error %s\n",
453  mc_group_id, sys_port, gport, opennsl_errmsg(rv));
454  return rv;
455  }
456 
457  rv = example_add_multicast_entry(unit, mc_group_id, &sys_port,
458  &encap_id, 1, is_egress);
459  if (rv != OPENNSL_E_NONE) {
460  printf("Failed to add multicast entry for mc_group_id: 0x%08x "
461  "phy_port: 0x%08x gport: 0x%08x, Error %s \n",
462  mc_group_id, sys_port, gport, opennsl_errmsg(rv));
463  return rv;
464  }
465 
466  return rv;
467 }
468 /* __doxy_func_body_end__ */
469 
470 /*****************************************************************/
481  opennsl_port_t phy_port, opennsl_gport_t gport)
482 {
483  int rv;
484 
485  /* add to vswitch */
486  rv = opennsl_vswitch_port_add(unit, vsi, gport);
487  if (rv != OPENNSL_E_NONE) {
488  printf("Failed to add a port to vswitch, Error %s\n", opennsl_errmsg(rv));
489  return rv;
490  }
491  if (verbose) {
492  printf("add access port 0x%08x to vswitch %d (0x%08x) \n\r", gport, vsi, vsi);
493  }
494 
495  /* update Multicast to have the added port */
496  rv = example_vlan_port_add(unit, g_vxlan.mc_group_id, phy_port, gport, 0);
497  if (rv != OPENNSL_E_NONE) {
498  printf("Failed to add a port to multicast group, phy_port: 0x%08x "
499  "gport: 0x%08x, Error %s\n", phy_port, gport, opennsl_errmsg(rv));
500  return rv;
501  }
502  if (verbose) {
503  printf("add access port 0x%08x to multicast in unit %d\n", gport, unit);
504  }
505  return OPENNSL_E_NONE;
506 }
507 /* __doxy_func_body_end__ */
508 
509 /*****************************************************************/
520  opennsl_port_t phy_port, opennsl_gport_t vlan_port)
521 {
522  int rv;
523  int encap_id;
524 
525  rv = opennsl_multicast_vlan_encap_get(unit, g_vxlan.mc_group_id, phy_port, vlan_port, &encap_id);
526  if (rv != OPENNSL_E_NONE) {
527  printf("Failed to get encapsulation ID for mc_group_id: 0x%08x "
528  "phy_port: 0x%08x vlan_port: 0x%08x, Error %s \n",
529  g_vxlan.mc_group_id, phy_port, vlan_port, opennsl_errmsg(rv));
530  return rv;
531  }
532 
533  rv = opennsl_multicast_ingress_delete(unit, g_vxlan.mc_group_id, phy_port, encap_id);
534  if (rv == OPENNSL_E_NOT_FOUND) {
535  printf("Failed to delete phy_port: 0x%08x from multicast group ID %d, Error %s\n",
536  phy_port, g_vxlan.mc_group_id, opennsl_errmsg(rv));
537  rv = OPENNSL_E_NONE;
538  }
539  printf ("Deleted phy_port: 0x%08x, encap_id:0x%08x from multicast group with ID: 0x%08x\n",
540  phy_port, encap_id, g_vxlan.mc_group_id);
541 
542 
543  /* remove from vswitch */
544  rv = opennsl_vswitch_port_delete(unit, vsi, vlan_port);
545  if (rv != OPENNSL_E_NONE) {
546  printf("Failed to remove port 0x%08x from vsi 0x%08x, Error %s\n",
547  vlan_port, vsi, opennsl_errmsg(rv));
548  return rv;
549  }
550  if (verbose) {
551  printf("Removed port 0x%08x from vswitch 0x%08x\n\r", vlan_port, vsi);
552  }
553 
554  return OPENNSL_E_NONE;
555 }
556 /* __doxy_func_body_end__ */
557 
558 /*****************************************************************/
568  int unit, int vlan, opennsl_multicast_t mc_group)
569 {
570  int rv;
571 
572  /* The vlan in this case may also represent a vsi. in that case, it should be created with a different api */
573  if (vlan <= OPENNSL_VLAN_MAX) {
574  rv = opennsl_vlan_create(unit, vlan);
575  } else {
576  rv = opennsl_vswitch_create_with_id(unit, vlan);
577  }
578  if ((rv != OPENNSL_E_NONE) && (rv != OPENNSL_E_EXISTS)) {
579  printf("Failed to opensl vlan(%d), Error %s", vlan, opennsl_errmsg(rv));
580  return rv;
581  }
582 
583  /* Set VLAN with MC is not required for VXLAN, removed below calls */
584  if (verbose >= 3) {
585  printf("Created vlan:%d \n", vlan);
586  }
587 
588  return rv;
589 }
590 /* __doxy_func_body_end__ */
591 
592 /*****************************************************************/
602  int unit,
603  int vlan,
604  int port)
605 {
606  int rv;
607  /* create vlan and add port to it */
608  rv = example_open_vlan_per_mc(unit, vlan, 0);
609  if (rv != OPENNSL_E_NONE) {
610  return;
611  }
612  rv = opennsl_vlan_gport_add(unit, vlan, port, 0);
613  if ((rv != OPENNSL_E_NONE) && (rv != OPENNSL_E_EXISTS)) {
614  printf("Failed to add port(0x%08x) to vlan %d, Error %s\n",
615  port, vlan, opennsl_errmsg(rv));
616  }
617  printf("Added port %d (0x%08x) to vlan %d\n", port, port, vlan);
618  return;
619 }
620 /* __doxy_func_body_end__ */
621 
622 /*****************************************************************/
632  int unit, int network_port, int access_port)
633 {
634  /*** create tunnel_vlan and add the network port ***/
635  if (ip_tunnel_glbl_info.tunnel_vlan != ip_tunnel_glbl_info.provider_vlan)
636  {
637  example_add_vlan_on_port(unit, ip_tunnel_glbl_info.tunnel_vlan, network_port);
638  }
639 
640  /*** create provider_vlan and add network port to it ***/
641  example_add_vlan_on_port(unit, ip_tunnel_glbl_info.provider_vlan, network_port);
642 
643  /*** create access_vlan and add user port to it ***/
644  example_add_vlan_on_port(unit, ip_tunnel_glbl_info.access_vlan, access_port);
645 }
646 /* __doxy_func_body_end__ */
647 
648 /*****************************************************************/
658  int unit, int *mc_group_id, int extra_flags)
659 {
660  int rv = OPENNSL_E_NONE;
661  int flags;
662 
663  flags = OPENNSL_MULTICAST_WITH_ID | extra_flags;
664  /* create ingress/egress MC */
665  if (egress_mc) {
667  } else {
669  }
670 
671  rv = opennsl_multicast_create(unit, flags, mc_group_id);
672  if (rv != OPENNSL_E_NONE) {
673  printf("Failed to create multicast group with ID %d, Error %s\n",
674  *mc_group_id, opennsl_errmsg(rv));
675  return rv;
676  }
677 
678  if (egress_mc) {
679  printf("Created egress mc_group %d (0x%x) \n", *mc_group_id, *mc_group_id);
680  } else {
681  printf("Created ingress mc_group %d (0x%x) \n", *mc_group_id, *mc_group_id);
682  }
683  /* save multicast group id */
684  g_vxlan.mc_group_id = *mc_group_id;
685 
686  return rv;
687 }
688 /* __doxy_func_body_end__ */
689 
690 /*****************************************************************/
698 int example_l3_egress_create(int unit, struct create_l3_egress_s *l3_egress)
699 {
700  int rv;
701  opennsl_l3_egress_t l3eg;
702  opennsl_if_t l3egid;
704 
705  /* FEC properties */
706  l3eg.intf = l3_egress->out_tunnel_or_rif;
707  l3eg.port = l3_egress->out_gport;
708  l3eg.encap_id = l3_egress->arp_encap_id;
709 
710  /* ARP */
711  memcpy(&l3eg.mac_addr, &l3_egress->next_hop_mac_addr, sizeof(opennsl_mac_t));
712  l3eg.vlan = l3_egress->vlan;
713  l3eg.qos_map_id = l3_egress->qos_map_id;
714 
715  l3eg.flags = l3_egress->l3_flags;
716  l3eg.flags2 = l3_egress->l3_flags2;
717  l3egid = l3_egress->fec_id;
718 
719  rv = opennsl_l3_egress_create(unit, l3_egress->allocation_flags, &l3eg, &l3egid);
720  if (rv != OPENNSL_E_NONE) {
721  printf("Failed to create egress egress object, Error %s\n", opennsl_errmsg(rv));
722  return rv;
723  }
724 
725  l3_egress->fec_id = l3egid;
726  l3_egress->arp_encap_id = l3eg.encap_id;
727 
728  if (verbose >= 1) {
729  printf("VLAN:%d created FEC-id = 0x%08x, ", l3eg.vlan,
730  l3_egress->fec_id);
731  printf("encap-id = 0x%08x ", l3_egress->arp_encap_id);
732  }
733 
734  if (verbose >= 2) {
735  printf("\n\toutRIF = 0x%08x out-port =%d ", l3_egress->out_tunnel_or_rif,
736  l3_egress->out_gport);
737  printf("mac-address: %02x:%02x:%02x:%02x:%02x:%02x",
738  l3eg.mac_addr[0], l3eg.mac_addr[1], l3eg.mac_addr[2],
739  l3eg.mac_addr[3], l3eg.mac_addr[4], l3eg.mac_addr[5]);
740  }
741 
742  if (verbose >= 1) {
743  printf("\n");
744  }
745 
746  return rv;
747 }
748 /* __doxy_func_body_end__ */
749 
750 /*****************************************************************/
769  int unit, struct create_l3_intf_s * l3_intf)
770 {
771  opennsl_l3_intf_t l3if, l3if_old;
772  int rv, station_id;
773  opennsl_l2_station_t station;
774  opennsl_l3_ingress_t l3_ing_if;
775  int is_urpf_mode_per_rif = 0;
776  int enable_public = 0;
777 
778  /* Initialize a opennsl_l3_intf_t structure. */
779  opennsl_l3_intf_t_init(&l3if);
780  opennsl_l3_intf_t_init(&l3if_old);
781  opennsl_l2_station_t_init(&station);
782  opennsl_l3_ingress_t_init(&l3_ing_if);
783 
784  if (!l3_intf->skip_mymac) {
785  /* set my-Mac global MSB */
786  station.flags = 0;
787  memcpy(station.dst_mac, l3_intf->my_global_mac, sizeof(opennsl_mac_t));
788  station.src_port_mask = 0; /* port is not valid */
789  station.vlan_mask = 0; /* vsi is not valid */
790  station.dst_mac_mask[0] = 0xff; /* dst_mac my-Mac MSB mask is -1 */
791  station.dst_mac_mask[1] = 0xff;
792  station.dst_mac_mask[2] = 0xff;
793  station.dst_mac_mask[3] = 0xff;
794  station.dst_mac_mask[4] = 0xff;
795  station.dst_mac_mask[5] = 0xff;
796 
797  rv = opennsl_l2_station_add(unit, &station_id, &station);
798  if (rv != OPENNSL_E_NONE) {
799  printf("Failed to add L2 station, Error %s\n", opennsl_errmsg(rv));
800  return rv;
801  }
802  }
803 
804  l3if.l3a_flags = OPENNSL_L3_WITH_ID; /* WITH-ID or without-ID does not really matter. Anyway for now RIF equal VSI */
805  if ((l3_intf->no_publc == 0) && ( /* Update the in_rif to have public searches enabled for vrf == 0 */
806  (l3_intf->vrf == 0 && example_is_qmx_device(unit)) ))
807  {
808  l3_intf->vrf_valid = 1;
809  enable_public = 1;
810  }
811 
812  l3if.l3a_vid = l3_intf->vsi;
813  l3if.l3a_ttl = 31; /* default settings */
814  if (l3_intf->ttl_valid) {
815  l3if.l3a_ttl = l3_intf->ttl;
816  }
817  l3if.l3a_mtu = 1524; /* default settings */
818  if (l3_intf->mtu_valid) {
819  l3if.l3a_mtu = l3_intf->mtu;
820  l3if.l3a_mtu_forwarding = l3_intf->mtu_forwarding;
821  }
823  l3_intf->rif = l3if.l3a_intf_id = l3_intf->vsi; /* In DNX Arch VSI always equal RIF */
824 
825  memcpy(l3if.l3a_mac_addr, l3_intf->my_lsb_mac, 6);
826  memcpy(l3if.l3a_mac_addr, l3_intf->my_global_mac, 4); /* ovewriting 4 MSB bytes with global MAC configuration */
827 
829 
830  l3if_old.l3a_intf_id = l3_intf->vsi;
831  rv = opennsl_l3_intf_get(unit, &l3if_old);
832  if (rv == OPENNSL_E_NONE) {
833  /* if L3 INTF already exists, replace it */
834  l3if.l3a_flags = l3if.l3a_flags | OPENNSL_L3_REPLACE;
835  printf("intf 0x%x already exist, just replacing\n",
836  l3if_old.l3a_intf_id);
837  }
838 
839  if (l3_intf->qos_map_valid) {
840  l3if.dscp_qos.qos_map_id = l3_intf->qos_map_id;
841  }
842 
843  rv = opennsl_l3_intf_create(unit, &l3if);
844  if (rv != OPENNSL_E_NONE) {
845  printf("Failed to create L3 interface, Error %s\n", opennsl_errmsg(rv));
846  return rv;
847  }
848 
849  if (l3_intf->vrf_valid || l3_intf->rpf_valid) {
850  l3_ing_if.flags = OPENNSL_L3_INGRESS_WITH_ID; /* must, as we update exist RIF */
851  l3_ing_if.vrf = l3_intf->vrf;
852 
853  if (l3_intf->rpf_valid && !is_urpf_mode_per_rif) {
854  /* Set uRPF global configuration */
856  if (rv != OPENNSL_E_NONE) {
857  return rv;
858  }
859  }
860  if (l3_intf->flags & OPENNSL_L3_RPF) {
861  l3_ing_if.urpf_mode = l3_intf->urpf_mode;
862  } else {
864  }
865 
867  || ((enable_public == 1) && example_is_qmx_device(unit))) {
869  }
872  }
873 
874  if (l3_intf->qos_map_valid) {
875  l3_ing_if.qos_map_id = l3_intf->qos_map_id;
876  }
877 
878  rv = opennsl_l3_ingress_create(unit, &l3_ing_if, &l3if.l3a_intf_id);
879  if (rv != OPENNSL_E_NONE) {
880  printf("Failed to create L3 ingress interface, Error %s\n", opennsl_errmsg(rv));
881  return rv;
882  }
883  l3_intf->rif = l3if.l3a_intf_id;
884  }
885 
886  printf
887  ("created ingress interface = %d, on vlan = %d in unit %d, vrf = %d, skip_mymac:%d ",
888  l3_intf->rif, l3_intf->vsi, unit, l3_intf->vrf, l3_intf->skip_mymac);
889  printf("mac: %02x:%02x:%02x:%02x:%02x:%02x\n\r",
890  l3_intf->my_global_mac[0], l3_intf->my_global_mac[1],
891  l3_intf->my_global_mac[2], l3_intf->my_global_mac[3],
892  l3_intf->my_global_mac[4], l3_intf->my_global_mac[5]);
893 
894  return rv;
895 }
896 /* __doxy_func_body_end__ */
897 
898 /*****************************************************************/
907  int unit, int provider_vlan)
908 {
909  int rv;
910  /* my-mac for LL termination */
911  opennsl_mac_t my_mac = MY_MAC;
912  struct create_l3_intf_s intf;
913 
914  memset(&intf, 0, sizeof(intf));
915  /* packets income on this vlan with my-mac will be LL termination */
916  intf.vsi = provider_vlan;
917  memcpy(intf.my_global_mac, my_mac, sizeof(opennsl_mac_t));
918  memcpy(intf.my_lsb_mac, my_mac, sizeof(opennsl_mac_t));
919  intf.ingress_flags = OPENNSL_L3_INGRESS_GLOBAL_ROUTE; /* enable public searches */
920 
921  rv = example_l3_intf_rif_create(unit, &intf);
922  if (rv != OPENNSL_E_NONE) {
923  printf("Failed to create L3 interface, Error %s\n", opennsl_errmsg(rv));
924  }
925  g_vxlan.prov_vlan_l3_intf_id = intf.rif;
926 
927  return rv;
928 }
929 /* __doxy_func_body_end__ */
930 
931 /*****************************************************************/
940  int unit, opennsl_gport_t *in_tunnel_gport_p)
941 {
942  int rv;
943  /* tunnel term info: according to DIP only */
944  opennsl_tunnel_terminator_t ip_tunnel_term;
945  struct ip_tunnel_s ip_tunnel_info = ip_tunnel_glbl_info.ip_tunnel_info;
946  /*** create IP tunnel terminator ***/
947  opennsl_tunnel_terminator_t_init(&ip_tunnel_term);
948  ip_tunnel_term.dip = ip_tunnel_info.sip; /* 170.0.0.17 */
949  ip_tunnel_term.dip_mask = 0xFFFFFFFF;
950  ip_tunnel_term.sip = ip_tunnel_info.dip; /* 171.0.0.17 */
951  ip_tunnel_term.sip_mask = 0xFFFFFFFF;
952  ip_tunnel_term.tunnel_if = -1; /* means don't overwite RIF */
953  ip_tunnel_term.type = opennslTunnelTypeVxlan;
954 
955  rv = opennsl_tunnel_terminator_create(unit, &ip_tunnel_term);
956  if (rv != OPENNSL_E_NONE) {
957  printf("Failed to create tunnel terminator, Error %s\n", opennsl_errmsg(rv));
958  }
959  if (verbose >= 1) {
960  printf("created tunnel terminator = 0x%08x \n", ip_tunnel_term.tunnel_id);
961  example_ip_tunnel_term_print_key("created tunnel term ", &ip_tunnel_term);
962  }
963  *in_tunnel_gport_p = ip_tunnel_term.tunnel_id;
964 
965  return rv;
966 }
967 /* __doxy_func_body_end__ */
968 
969 /*****************************************************************/
979  int unit, int tunnel_vlan, opennsl_gport_t *tunnel_gportp)
980 {
981  int rv;
982 
983  /* tunnel info */
984  opennsl_tunnel_initiator_t ip_tunnel;
985  struct ip_tunnel_s ip_tunnel_info = ip_tunnel_glbl_info.ip_tunnel_info;
986  int tunnel_itf = 0;
987 
988  /*** create tunnel ***/
990  ip_tunnel.dip = ip_tunnel_info.dip; /* default: 171.0.0.17 */
991  ip_tunnel.sip = ip_tunnel_info.sip; /* default: 170.0.0.17 */
992  ip_tunnel.flags |= ip_tunnel_info.flags;
993  ip_tunnel.ttl = ip_tunnel_info.ttl; /* default: 50 */
994  ip_tunnel.type = ip_tunnel_glbl_info.tunnel_type; /* default: opennslTunnelTypeIpAnyIn4 */
995  ip_tunnel.vlan = tunnel_vlan;
996  ip_tunnel.dscp_sel = ip_tunnel_info.dscp_sel; /* default: opennslTunnelDscpAssign */
997  if (opennslTunnelDscpAssign == ip_tunnel.dscp_sel)
998  {
999  ip_tunnel.dscp = ip_tunnel_info.dscp; /* default: 11 */
1000  }
1002  rv = example_ip_tunnel_add(unit, &tunnel_itf, &ip_tunnel);
1003  if (rv != OPENNSL_E_NONE) {
1004  printf("Failed to add IP tunnel, Error %s\n", opennsl_errmsg(rv));
1005  }
1006  if (verbose >= 1) {
1007  printf("Created IP tunnel on intf : 0x%08x ", tunnel_itf);
1008  print_ip_addr(" SIP:", ip_tunnel.sip);
1009  print_ip_addr(" DIP:", ip_tunnel.dip);
1010  printf("\n");
1011  }
1013  outlif_to_count2 = ip_tunnel.tunnel_id;
1014  }
1015  /*** save it in global data */
1016  g_vxlan.tunnel_init_intf_id = tunnel_itf;
1017 
1018  /* refernces to created tunnels as gport */
1019  *tunnel_gportp = ip_tunnel.tunnel_id;
1020  if (verbose >= 1) {
1021  printf("created tunnel initiator gport : 0x%08x vlan : %d "
1022  "g_vxlan.tunnel_init_intf_id : 0x%08x\n", *tunnel_gportp,
1023  tunnel_vlan, g_vxlan.tunnel_init_intf_id);
1024  }
1025 
1026  return rv;
1027 }
1028 /* __doxy_func_body_end__ */
1029 
1030 /*****************************************************************/
1041  int unit, int tunnel_vlan,
1042  int tunnel_port, opennsl_if_t * tunnel_fec_p)
1043 {
1044  int rv;
1045 
1046  /* tunnel info */
1047  opennsl_mac_t next_hop_mac;
1048 
1049  /*** create egress object: points into tunnel, with allocating FEC, and da-mac = next_hop_mac ***/
1050  struct create_l3_egress_s l3eg1;
1051 
1052  memcpy(next_hop_mac, ip_tunnel_glbl_info.ip_tunnel_info.da, sizeof(opennsl_mac_t));
1053  memset(&l3eg1, 0, sizeof(l3eg1));
1054  memcpy(l3eg1.next_hop_mac_addr, next_hop_mac, sizeof(opennsl_mac_t));
1055  l3eg1.out_tunnel_or_rif = g_vxlan.tunnel_init_intf_id;
1056  l3eg1.out_gport = portmap[tunnel_port];
1057  l3eg1.vlan = tunnel_vlan;
1058  l3eg1.fec_id = 0; /* This may not matter so much, sarath */
1059  l3eg1.arp_encap_id = 0;
1060 
1061  rv = example_l3_egress_create(unit, &l3eg1);
1062  if (rv != OPENNSL_E_NONE) {
1063  printf("Failed to create L3 egress object, Error %s\n", opennsl_errmsg(rv));
1064  return rv;
1065  }
1066 
1067  /* interface for ip_tunnel is egress-object (FEC) */
1068  *tunnel_fec_p = l3eg1.fec_id;
1069  if (verbose >= 1) {
1070  printf("Created FEC-id = 0x%08x\n", *tunnel_fec_p);
1071  }
1072 
1073  return rv;
1074 }
1075 /* __doxy_func_body_end__ */
1076 
1077 /*****************************************************************/
1089 {
1090 
1091  opennsl_l3_intf_t l3_intf;
1092  int rv = OPENNSL_E_NONE;
1093 
1094  opennsl_l3_intf_t_init(&l3_intf);
1095 
1096  /* if given ID is set, then use it as placement of the ipv4-tunnel */
1097  if (*itf != 0) {
1098  OPENNSL_GPORT_TUNNEL_ID_SET(tunnel->tunnel_id, *itf);
1099  tunnel->flags |= OPENNSL_TUNNEL_WITH_ID;
1100  }
1101 
1102  rv = opennsl_tunnel_initiator_create(unit, &l3_intf, tunnel);
1103  if (rv != OPENNSL_E_NONE) {
1104  printf("Failed to create tunnel initiator, Error %s\n", opennsl_errmsg(rv));
1105  return rv;
1106  }
1107 
1108  /* include interface-id points to the tunnel */
1109  *itf = l3_intf.l3a_intf_id;
1110  return rv;
1111 }
1112 /* __doxy_func_body_end__ */
1113 
1114 /*****************************************************************/
1122  struct vxlan_port_add_s * vxlan_port_add)
1123 {
1124 
1125  memset(vxlan_port_add, 0, sizeof(*vxlan_port_add));
1126 
1127  /* by default, egress orientatino is set by vxlan port */
1128  vxlan_port_add->set_egress_orientation_using_vxlan_port_add = 1;
1129 
1130  return OPENNSL_E_NONE;
1131 }
1132 /* __doxy_func_body_end__ */
1133 
1134 /*****************************************************************/
1145 int example_multicast_vxlan_port_add(int unit, int mc_group_id,
1146  int sys_port, int gport, uint8 is_egress)
1147 {
1148 
1149  int encap_id;
1150  int rv = OPENNSL_E_NONE;
1151 
1152  rv = opennsl_multicast_vxlan_encap_get(unit, mc_group_id, sys_port, gport, &encap_id);
1153  if (rv != OPENNSL_E_NONE) {
1154  printf
1155  ("Failed to vxlan encapsulation ID for mc_group_id: 0x%08x "
1156  "phy_port: 0x%08x gport: 0x%08x, Error %s\n",
1157  mc_group_id, sys_port, gport, opennsl_errmsg(rv));
1158  return rv;
1159  }
1160  rv = opennsl_multicast_ingress_add(unit, mc_group_id, sys_port, encap_id);
1161  /* if the MC entry already exist, then we shouldn't add it twice to the multicast group */
1162  if (rv == OPENNSL_E_EXISTS) {
1163  printf("The multicast entry already exists \n");
1164  rv = OPENNSL_E_NONE;
1165  } else if (rv != OPENNSL_E_NONE) {
1166  printf("Failed to update ingress multicast group for mc_group_id: 0x%08x "
1167  "phy_port: 0x%08x encap_id: 0x%08x, Error %s\n",
1168  mc_group_id, sys_port, encap_id, opennsl_errmsg(rv));
1169  return rv;
1170  }
1171  printf("Added sys_port %d to mc_group_id %d encap_id: 0x%08x\n", sys_port, mc_group_id, encap_id);
1172 
1173  return rv;
1174 }
1175 /* __doxy_func_body_end__ */
1176 
1177 /*****************************************************************/
1186  int unit, struct vxlan_port_add_s *vxlan_port_add)
1187 {
1188  int rv = OPENNSL_E_NONE;
1189  opennsl_vxlan_port_t vxlan_port;
1190 
1191  opennsl_vxlan_port_t_init(&vxlan_port);
1192 
1194  vxlan_port.match_port = vxlan_port_add->in_port;
1195  vxlan_port.match_tunnel_id = vxlan_port_add->in_tunnel;
1196  vxlan_port.egress_if = vxlan_port_add->egress_if;
1197  vxlan_port.egress_tunnel_id = vxlan_port_add->out_tunnel;
1198  vxlan_port.flags = vxlan_port_add->flags | OPENNSL_VXLAN_PORT_EGRESS_TUNNEL;
1199 
1200  /* set orientation, work for Jericho.
1201  * For Jericho, we configure orientation at ingress (inLif) and egress (outLif):
1202  * ingress orientation is configured at opennsl_vxlan_port_add.
1203  * egress orientation can be configured using opennsl_vxlan_port_add or at opennsl_port_class_set
1204  */
1205  /* flag indicating network orientation.
1206  * Used to configure ingress orientation and optionally egress orientation */
1207  vxlan_port.flags |= OPENNSL_VXLAN_PORT_NETWORK;
1208  vxlan_port.network_group_id = vxlan_port_add->network_group_id; /* TO FIX g_vxlan.vxlan_network_group_id; */
1209 
1210  rv = opennsl_vxlan_port_add(unit, vxlan_port_add->vpn, &vxlan_port);
1211  if (rv != OPENNSL_E_NONE) {
1212  printf("Failed to add vxlan port, Error %s\n", opennsl_errmsg(rv));
1213  return rv;
1214  }
1215 
1216  vxlan_port_add->vxlan_port_id = vxlan_port.vxlan_port_id;
1217 
1218  if (verbose >= 2) {
1219  printf("vxlan port created, vxlan_port_id: 0x%08x \n",
1220  vxlan_port.vxlan_port_id);
1221  printf("vxlan port is config with:\n");
1222  printf(" ip in tunnel termination gport:0x%08x \n", vxlan_port_add->in_tunnel);
1223  if (vxlan_port_add->egress_if != 0) {
1224  printf(" FEC entry (contains ip tunnel encapsulation information):0x%08x \n",
1225  vxlan_port_add->egress_if);
1226  } else {
1227  printf(" ip tunnel initiator gport:0x%08x\n", vxlan_port_add->out_tunnel);
1228  }
1229  printf(" vpn: 0x%08x\n\r", vxlan_port_add->vpn);
1230  printf(" vxlan lif orientation: network_group_id = %d\n\r", vxlan_port_add->network_group_id);
1231  }
1232 
1233  rv = example_multicast_vxlan_port_add(unit, g_vxlan.mc_group_id,
1234  vxlan_port.match_port, vxlan_port.vxlan_port_id, egress_mc);
1235  if (rv != OPENNSL_E_NONE) {
1236  printf("Failed to add vxlan port to multicast group, Error %s\n", opennsl_errmsg(rv));
1237  return rv;
1238  }
1239  if (verbose >= 2) {
1240  printf("add vxlan-port 0x%08x to VPN flooding group %d (0x%08x)\n\r",
1241  vxlan_port.vxlan_port_id, g_vxlan.mc_group_id, g_vxlan.mc_group_id);
1242  }
1243 
1244  return rv;
1245 }
1246 /* __doxy_func_body_end__ */
1247 
1248 /*****************************************************************/
1256 void vxlan_init(int unit, struct vxlan_s *vx_info)
1257 {
1258  if (vx_info != NULL) {
1259  memcpy(&g_vxlan, vx_info, sizeof(g_vxlan));
1260  }
1261 }
1262 /* __doxy_func_body_end__ */
1263 
1264 /*****************************************************************/
1272 void vxlan_struct_get(struct vxlan_s *vx_info)
1273 {
1274  memcpy(vx_info, &g_vxlan, sizeof(g_vxlan));
1275 }
1276 /* __doxy_func_body_end__ */
1277 
1278 /*****************************************************************/
1287 int example_vxlan_open_vpn(int unit, int vpn, int vni)
1288 {
1289  int rv = OPENNSL_E_NONE;
1290  int mc_group_id = vpn;
1291 
1292  egress_mc = 0;
1293  rv = example_multicast_group_open(unit, &mc_group_id,
1295  if (rv != OPENNSL_E_NONE) {
1296  printf("Failed to create multicast group, Error %s\n", opennsl_errmsg(rv));
1297  return rv;
1298  }
1299 
1300  opennsl_vxlan_vpn_config_t vpn_config;
1301  opennsl_vxlan_vpn_config_t_init(&vpn_config);
1302 
1303  vpn_config.flags =
1305  vpn_config.vpn = vpn;
1306  vpn_config.broadcast_group = mc_group_id;
1307  vpn_config.unknown_unicast_group = mc_group_id;
1308  vpn_config.unknown_multicast_group = mc_group_id;
1309  vpn_config.vnid = vni;
1310  if (g_vxlan.vxlan_vdc_enable) {
1311  vpn_config.match_port_class = vdc_port_class;
1312  }
1313 
1314  rv = opennsl_vxlan_vpn_create(unit, &vpn_config);
1315  if (rv != OPENNSL_E_NONE) {
1316  printf("Failed to create vxlan vpn, Error %s\n", opennsl_errmsg(rv));
1317  return rv;
1318  }
1319  if (verbose >= 1) {
1320  printf("Created vpn %d (0x%08x)\n\r", vpn, vpn);
1321  }
1322 
1323  return rv;
1324 }
1325 /* __doxy_func_body_end__ */
1326 
1327 /*****************************************************************/
1337  opennsl_gport_t *port_id)
1338 {
1339  int rv;
1340  opennsl_vlan_port_t vport1;
1341  opennsl_vlan_port_t_init(&vport1);
1343  vport1.port = in_port;
1344  vport1.match_vlan = ip_tunnel_glbl_info.access_vlan;
1345  vport1.egress_vlan = ip_tunnel_glbl_info.access_vlan;
1346  vport1.flags = 0;
1347  vport1.vsi = 0;
1348  rv = opennsl_vlan_port_create(unit, &vport1);
1349 
1350  if (rv != OPENNSL_E_NONE) {
1351  printf("Failed to create vlan_port filter, Error %s\n", opennsl_errmsg(rv));
1352  return rv;
1353  }
1354 
1355  if (verbose >= 2) {
1356  printf
1357  ("Add vlan-port-id: 0x%08x in-port: %d (0x%08x) match_vlan: %d "
1358  "egress_vlan: %d match_inner_vlan: %d\n\r", vport1.vlan_port_id,
1359  vport1.port, vport1.port, vport1.match_vlan, vport1.egress_vlan,
1360  vport1.match_inner_vlan);
1361  }
1362 
1363  /* handle of the created gport */
1364  *port_id = vport1.vlan_port_id;
1365 
1366  return rv;
1367 }
1368 /* __doxy_func_body_end__ */
1369 
1370 /*****************************************************************/
1383  int unit,
1384  int network_port,
1385  int access_port,
1386  int vpn_id)
1387 {
1388  int rv = OPENNSL_E_NONE;
1389  int vxlan_port_flags = 0;
1390  struct vxlan_port_add_s vxlan_port_add;
1391 
1392  /* init vxlan global */
1393  struct vxlan_s vxlan_param;
1394  vxlan_struct_get(&vxlan_param);
1395  if (vpn_id >= 0) {
1396  vxlan_param.vpn_id = vpn_id;
1397  }
1398  vxlan_init(unit, &vxlan_param);
1399  vpn_id = g_vxlan.vpn_id;
1400  init_portmap(unit);
1401 
1402  printf("Parameters \n");
1403  printf("Ports (Network: %d, Access: %d)\n", network_port, access_port);
1404  printf("Vlans (Provider:%d Tunnel:%d Access:%d)\n",
1405  ip_tunnel_glbl_info.provider_vlan,
1406  ip_tunnel_glbl_info.tunnel_vlan,
1407  ip_tunnel_glbl_info.access_vlan);
1408  printf("VPN: %d VNI: %d(0x%x)\n", vpn_id, g_vxlan.vni, g_vxlan.vni);
1409  g_vxlan.access_port = access_port;
1410  g_vxlan.network_port = network_port;
1411 
1412  example_vxlan_port_s_clear(&vxlan_port_add);
1413  /* config ports as local ports i.e Works as egress port */
1415 
1416  verbose = 10;
1417 
1418  /* init L2 VXLAN module */
1419  rv = opennsl_vxlan_init(unit);
1420  if (rv != OPENNSL_E_NONE) {
1421  printf("Failed to initialize vxlan, Error %s\n", opennsl_errmsg(rv));
1422  }
1423 
1424  /*** Add the ports to VLANs ***/
1425  example_add_ports_to_vlans(unit, network_port, access_port);
1426 
1427  /* build L2 VPN */
1428  rv = example_vxlan_open_vpn(unit, vpn_id, g_vxlan.vni);
1429  if (rv != OPENNSL_E_NONE) {
1430  printf("Failed to open vpn %d, Error %s\n", vpn_id, opennsl_errmsg(rv));
1431  }
1432 
1433  /* Create inLif for access port */
1434  rv = example_vlan_inLif_create(unit, access_port, &g_vxlan.vlan_inLif);
1435  if (rv != OPENNSL_E_NONE) {
1436  printf("Failed to create VLAN inLIF 0x%08x, Error %s\n", g_vxlan.vlan_inLif,
1437  opennsl_errmsg(rv));
1438  }
1439 
1440  /* Add inLif to VSI and add it flood MC group */
1441  rv = example_add_inLif_to_vswitch(unit, vpn_id, access_port, g_vxlan.vlan_inLif);
1442  if (rv != OPENNSL_E_NONE) {
1443  printf("Failed to add inLif to VSI or adding access port to multicast "
1444  "group, Error %s\n", opennsl_errmsg(rv));
1445  return rv;
1446  }
1447 
1448  /*** build tunnel initiator ***/
1449  rv = example_vxlan_egress_tunnel_create(unit, ip_tunnel_glbl_info.tunnel_vlan,
1450  &g_vxlan.tunnel_init_gport);
1451  if (rv != OPENNSL_E_NONE) {
1452  printf("Failed to build tunnel initiator network_port %d, Error %s\n",
1453  network_port, opennsl_errmsg(rv));
1454  }
1455 
1456  /*** build tunnel FEC ***/
1457  rv = example_vxlan_egress_tunnel_fec_create(unit, ip_tunnel_glbl_info.tunnel_vlan,
1458  network_port, &g_vxlan.vxlan_fec_intf_id);
1459  if (rv != OPENNSL_E_NONE) {
1460  printf("Failed to create FEC, network_port %d, Error %s\n",
1461  network_port, opennsl_errmsg(rv));
1462  }
1463 
1464  if (verbose >= 2) {
1465  printf("out-tunnel gport-id: 0x%08x FEC-id:0x%08x\n\r",
1466  g_vxlan.tunnel_init_gport, g_vxlan.vxlan_fec_intf_id);
1467  }
1468 
1469  /* tunnel termination configuration */
1470  if (g_vxlan.dip_sip_vrf_using_my_vtep_index_mode == 0) {
1471  /*** build tunnel termination ***/
1473  if (rv != OPENNSL_E_NONE) {
1474  printf("Failed to build tunnel termination, Error %s\n", opennsl_errmsg(rv));
1475  return rv;
1476  }
1477 
1478  /*** create L3 interface on provider_vlan, not using it explicitly, but used in pipeline */
1479  rv = example_ip_tunnel_term_create_l3_intf(unit, ip_tunnel_glbl_info.provider_vlan);
1480  if (rv != OPENNSL_E_NONE) {
1481  printf("Failed to create L3 interface on provider VLAN, Error %s\n", opennsl_errmsg(rv));
1482  }
1483 
1484  if (verbose >= 2) {
1485  printf("in-tunnel gport-id: 0x%08x L3 itf:%x\r", g_vxlan.tunnel_term_gport, g_vxlan.prov_vlan_l3_intf_id);
1486  }
1487  /* build l2 vxlan ports */
1488  vxlan_port_add.network_group_id = g_vxlan.vxlan_network_group_id;
1489  }
1490  /* create VxLAN gport using tunnel inlif */
1491  vxlan_port_add.vpn = vpn_id;
1492  vxlan_port_add.in_port = network_port;
1493  vxlan_port_add.in_tunnel = g_vxlan.tunnel_term_gport;
1494  vxlan_port_add.out_tunnel = g_vxlan.tunnel_init_gport;
1495  vxlan_port_add.egress_if = g_vxlan.vxlan_fec_intf_id;
1496  vxlan_port_add.flags = vxlan_port_flags;
1497 
1498  rv = example_vxlan_port_add(unit, &vxlan_port_add);
1499  if (rv != OPENNSL_E_NONE) {
1500  printf("Failed to add vxlan tunnel, in_gport=0x%08x --> out_intf=0x%08x, "
1501  "Error %s\n", g_vxlan.tunnel_term_gport,
1502  g_vxlan.vxlan_fec_intf_id, opennsl_errmsg(rv));
1503  return rv;
1504  }
1505 
1506  g_vxlan.vxlan_gport = vxlan_port_add.vxlan_port_id;
1507 
1508  if (verbose >= 2) {
1509  printf("vxlan port created, vxlan_port_id: 0x%08x \n", g_vxlan.vxlan_gport);
1510  }
1511 
1512  /* add mact entries point to created gports */
1513  rv = example_l2_addr_add(unit, g_vxlan.user_mac_address, vpn_id, g_vxlan.vlan_inLif);
1514  if (rv != OPENNSL_E_NONE) {
1515  printf("Failed to update FDB for vlan %d port 0x%08x, Error %s\n",
1516  vpn_id, g_vxlan.vlan_inLif, opennsl_errmsg(rv));
1517  return rv;
1518  }
1519 
1520  rv = example_l2_addr_add(unit, g_vxlan.tunnel_mac_address, vpn_id, g_vxlan.vxlan_gport);
1521  if (rv != OPENNSL_E_NONE) {
1522  printf("Failed to update FDB for vlan %d port 0x%08x, Error %s\n",
1523  vpn_id, g_vxlan.vxlan_gport, opennsl_errmsg(rv));
1524  return rv;
1525  }
1526 
1527  /* adding a registered MC using flood MC */
1528  opennsl_l2_addr_t l2addr;
1529  opennsl_l2_addr_t_init(&l2addr, g_vxlan.mc_mac, vpn_id);
1530 
1531  l2addr.l2mc_group = g_vxlan.mc_group_id;
1533 
1534  rv = opennsl_l2_addr_add(unit, &l2addr);
1535  if (rv != OPENNSL_E_NONE) {
1536  printf("Failed to FDB with multicast entry, Error %s\n", opennsl_errmsg(rv));
1537  return rv;
1538  }
1539 
1540  return rv;
1541 }
1542 /* __doxy_func_body_end__ */
1543 
1544 /*****************************************************************/
1551 int main(int argc, char *argv[])
1552 {
1553  opennsl_error_t rv;
1554  int choice;
1555  int index = 0;
1556  int unit = DEFAULT_UNIT;
1557  int port_a;
1558  int port_n;
1559  int vpn_id;
1560 
1561  if(strcmp(argv[0], "gdb") == 0)
1562  {
1563  index = 1;
1564  }
1565 
1566  if((argc != (index + 1)) || ((argc > (index + 1)) && (strcmp(argv[index + 1], "--help") == 0))) {
1567  printf("%s\n\r", example_usage);
1568  return OPENNSL_E_PARAM;
1569  }
1570 
1571  /* Initialize the system. */
1572  printf("Initializing the switch device.\r\n");
1574 
1575  if(rv != OPENNSL_E_NONE) {
1576  printf("\r\nFailed to initialize the switch device. Error %s\r\n",
1577  opennsl_errmsg(rv));
1578  return rv;
1579  }
1580 
1581  /* cold boot initialization commands */
1582  rv = example_port_default_config(unit);
1583  if (rv != OPENNSL_E_NONE) {
1584  printf("\r\nFailed to apply default config on ports, rv = %d (%s).\r\n",
1585  rv, opennsl_errmsg(rv));
1586  }
1587 
1588  while (1) {
1589  printf("\r\nUser menu: Select one of the following options\r\n");
1590  printf("1. Configure VxLAN segment\n");
1591 #ifdef INCLUDE_DIAG_SHELL
1592  printf("9. Launch diagnostic shell\n");
1593 #endif
1594  printf("0. Quit the application\n");
1595 
1597  {
1598  printf("Invalid option entered. Please re-enter.\n");
1599  continue;
1600  }
1601  switch(choice){
1602 
1603  case 1:
1604  {
1605  /* Configure VXLAN settings for access and network ports */
1606  printf("a. Enter Access port number\n");
1608  {
1609  printf("Invalid option entered. Please re-enter.\n");
1610  continue;
1611  }
1612 
1613  printf("b. Enter Network port number\n");
1615  {
1616  printf("Invalid option entered. Please re-enter.\n");
1617  continue;
1618  }
1619 
1620  printf("c. Enter VPN ID (Ex: 9216)\n");
1622  {
1623  printf("Invalid option entered. Please re-enter.\n");
1624  continue;
1625  }
1626 
1627  rv = example_vxlan(unit, port_n, port_a, vpn_id);
1628  if(rv != OPENNSL_E_NONE)
1629  {
1630  printf("\r\nVxLAN configuration has failed.\n");
1631  return rv;
1632  }
1633 
1634  printf("\r\nVxLAN configuration is done successfully\n");
1635  break;
1636  }
1637 
1638 #ifdef INCLUDE_DIAG_SHELL
1639  case 9:
1640  {
1641  opennsl_driver_shell();
1642  break;
1643  }
1644 #endif
1645 
1646  case 0:
1647  {
1648  printf("Exiting the application.\n");
1649  rv = opennsl_driver_exit();
1650  return rv;
1651  }
1652  default:
1653  break;
1654  } /* End of switch */
1655  } /* End of while */
1656 
1657  return OPENNSL_E_NONE;
1658 }
1659 /* __doxy_func_body_end__ */