def setup_v4routelist(self, route, route_event, route_type): # # Create an SLRoute object and set its attributes # routev4 = sl_route_ipv4_pb2.SLRoutev4() # Ignore routes that are not allowed if not self.plugin.is_allowed_route(route): return # IP Prefix routev4.Prefix = int( ipaddress.ip_address(self.plugin.get_route_prefix(route))) # Prefix Length routev4.PrefixLen = self.plugin.get_route_prefixlen(route) # Administrative distance Loaded based on User defined proto weight admin_distance = self.plugin.get_admin_distance(route) if admin_distance is not None: routev4.RouteCommon.AdminDistance = admin_distance else: logger.debug("No Admin Distance specified by User, skipping route") return # Create an SLRoutePath path object. path = sl_route_common_pb2.SLRoutePath() # Fill in the path attributes. # Path next hop address if route_event != 'delete': if route_type == ROUTE_SINGLEPATH: path.NexthopAddress.V4Address = int( ipaddress.ip_address(self.plugin.get_route_gateway(route))) nh_interface = self.plugin.get_route_xrifname(route) if nh_interface['status'] == 'success': if nh_interface['ifname'] != '': path.NexthopInterface.Name = nh_interface['ifname'] else: logger.debug( "OIF not allowed, skipping next hop interface setting" ) else: logger.debug( "Error while fetching the next hop interface, skip route" ) return elif route_type == ROUTE_OIF: # For now, we ignore OIF only routes, SL-API expects a gateway to be specified logger.debug("Gateway is not specified, skipping this route") return routev4.PathList.extend([path]) # # Append the route to the route list (bulk routes) # self.v4routeList.append(routev4)
def route_serializer(batch, paths, next_hops): """Agnostic function that returns either an IPv4 or IPv6 serializer instance. Not all fields are required to instantiate `SLRoutev4Msg`| `SLRoutev6Msg` classes. Therefore, conditions are specified to determine if certain keys exist within the dictionary parameters. If said keys do exist, then that attribute for the serializer class is assigned. Otherwise, fields are omitted, but the class is still instantiated. Returns: Tuple: sl_route_ipv4_pb2.SLRoutev4Msg|sl_route_ipv6_pb2.SLRoutev6Msg Next Prefix based on range value """ Message = collections.namedtuple('Message', [ 'af', 'serializer', 'route', ]) if batch['af'] == 4: # IPv4 message types. ipv4_or_ipv6 = Message(batch['af'], sl_route_ipv4_pb2.SLRoutev4Msg, sl_route_ipv4_pb2.SLRoutev4) elif batch['af'] == 6: # IPv6 message types. ipv4_or_ipv6 = Message(batch['af'], sl_route_ipv6_pb2.SLRoutev6Msg, sl_route_ipv6_pb2.SLRoutev6) # Create either a `SLRoutev4Msg` message or a `SLRoutev6Msg` # message. serializer = ipv4_or_ipv6.serializer() if 'vrf_name' in batch: serializer.VrfName = batch['vrf_name'] if 'correlator' in batch: serializer.Correlator = batch['correlator'] if 'routes' in batch: routes = [] for route in batch['routes']: # Create either a `SLRoutev4` message or a `SLRoutev6` # message. if 'prefix' in route: if ipv4_or_ipv6.af == 4: value = int(ipaddress.ip_address(route['prefix'])) elif ipv4_or_ipv6.af == 6: # `packed` returns a `bytearray` object, therefore, # the result must be cast to type `str`. value = int(ipaddress.ip_address(route['prefix'])) # local_label = 0 if 'local_label' in route: local_label = route['local_label'] # for i in xrange(route['range']): r = ipv4_or_ipv6.route() if 'prefix' in route: if ipv4_or_ipv6.af == 4: r.Prefix = value elif ipv4_or_ipv6.af == 6: # `packed` return a `bytearray` object, therefore, # the result must be cast to type `str`. r.Prefix = (str(ipaddress.IPv6Address(value).packed)) if 'prefix_len' in route: if ipv4_or_ipv6.af == 4: r.PrefixLen = (route['prefix_len']) elif ipv4_or_ipv6.af == 6: r.PrefixLen = (route['prefix_len']) if 'admin_dist' in route: r.RouteCommon.AdminDistance = route['admin_dist'] if 'local_label' in route: r.RouteCommon.LocalLabel = local_label local_label = local_label + 1 if 'tag' in route: r.RouteCommon.Tag = route['tag'] ps = [] for path in paths[route['path']]: p = sl_route_common_pb2.SLRoutePath() if ipv4_or_ipv6.af == 4: if (path['nexthop'] and 'v4_addr' in next_hops[path['nexthop']]): p.NexthopAddress.V4Address = (int( ipaddress.ip_address( next_hops[path['nexthop']]['v4_addr']))) elif ipv4_or_ipv6.af == 6: if (path['nexthop'] and 'v6_addr' in next_hops[path['nexthop']]): p.NexthopAddress.V6Address = (str( ipaddress.ip_address( (next_hops[path['nexthop']]['v6_addr'] )).packed)) if 'if_name' in next_hops[path['nexthop']]: p.NexthopInterface.Name = ( next_hops[path['nexthop']]['if_name']) if 'load_metric' in path: p.LoadMetric = path['load_metric'] if 'metric' in path: p.Metric = path['metric'] if 'vrf_name' in next_hops[path['nexthop']]: p.VrfName = next_hops[path['nexthop']]['vrf_name'] if 'path_id' in path: p.PathId = path['path_id'] # Bitmap bitmap = [] if 'p_bitmap' in path: for bmap in path['p_bitmap']: bitmap.append(bmap) p.ProtectedPathBitmap.extend(bitmap) # Add labels labels = [] if 'labels' in path: for label in path['labels']: labels.append(label) p.LabelStack.extend(labels) # Add remote addresses remote_addr = [] if ipv4_or_ipv6.af == 4: if 'v4_remote_addr' in path: for r_addr in path['v4_remote_addr']: sl_r_addr = sl_common_types_pb2.SLIpAddress() sl_r_addr.V4Address = (int( ipaddress.ip_address(r_addr))) remote_addr.append(sl_r_addr) p.RemoteAddress.extend(remote_addr) elif ipv4_or_ipv6.af == 6: if 'v6_remote_addr' in path: for r_addr in path['v6_remote_addr']: sl_r_addr = sl_common_types_pb2.SLIpAddress() sl_r_addr.V6Address = (str( ipaddress.ip_address(r_addr).packed)) remote_addr.append(sl_r_addr) p.RemoteAddress.extend(remote_addr) # Append the `SLRoutePath` object to the `ps` list # object and extend the `sl_path_list` object of the # route. ps.append(p) r.PathList.extend(ps) # Append the `SLRoutev4`|`SLRoutev6` object to the `routes` # list object and extend the `sl_routes` object of the # serializer. routes.append(r) # Increment prefix value = util.sl_util_inc_prefix(value, route['prefix_len'], 1, ipv4_or_ipv6.af) serializer.Routes.extend(routes) if ipv4_or_ipv6.af == 4: value_str = str(ipaddress.IPv4Address(value)) else: value_str = str(ipaddress.IPv6Address(value)) return (serializer, value_str, local_label)
def route_operation(channel, oper): # Create the gRPC stub. stub = sl_route_ipv4_pb2.beta_create_SLRoutev4Oper_stub(channel) # Create an empty list of routes. routeList = [] # Create the SLRoutev4Msg message holding the SLRoutev4 object list rtMsg = sl_route_ipv4_pb2.SLRoutev4Msg() # Fill in the message attributes attributes. # VRF Name rtMsg.VrfName = 'default' # Fill in the routes for i in range(10): # # Create an SLRoutev4 object and set its attributes # route = sl_route_ipv4_pb2.SLRoutev4() # IP Prefix route.Prefix = (int(ipaddress.ip_address('20.0.' + str(i) + '.0'))) # Prefix Length route.PrefixLen = 24 # Administrative distance route.RouteCommon.AdminDistance = 2 # # Set the route's paths. # A Route might have one or many paths # # Create an empty list of paths as a placeholder for these paths paths = [] # Create an SLRoutePath path object. path = sl_route_common_pb2.SLRoutePath() # Fill in the path attributes. # Path next hop address path.NexthopAddress.V4Address = (int( ipaddress.ip_address('10.10.10.1'))) # Next hop interface name path.NexthopInterface.Name = 'GigabitEthernet0/0/0/0' # # Add the path to the list # paths.append(path) # Let's create another path as equal cost multi-path (ECMP) path = sl_route_common_pb2.SLRoutePath() path.NexthopAddress.V4Address = (int( ipaddress.ip_address('10.10.10.2'))) path.NexthopInterface.Name = 'GigabitEthernet0/0/0/0' # # Add the path to the list # paths.append(path) # # Assign the paths to the route object # Note: Route Delete operations do not require the paths # if oper != sl_common_types_pb2.SL_OBJOP_DELETE: route.PathList.extend(paths) # # Append the route to the route list (bulk routes) # routeList.append(route) # # Done building the routeList, assign it to the route message. # rtMsg.Routes.extend(routeList) # # Make an RPC call # Timeout = 10 # Seconds rtMsg.Oper = oper # Desired ADD, UPDATE, DELETE operation response = stub.SLRoutev4Op(rtMsg, Timeout) # # Check the received result from the Server # if (sl_common_types_pb2.SLErrorStatus.SL_SUCCESS == response.StatusSummary.Status): print "Route %s Success!" % ( sl_common_types_pb2.SLObjectOp.keys()[oper]) else: print "Error code for route %s is 0x%x" % ( sl_common_types_pb2.SLObjectOp.keys()[oper], response.StatusSummary.Status) # If we have partial failures within the batch, let's print them if (response.StatusSummary.Status == sl_common_types_pb2.SLErrorStatus.SL_SOME_ERR): for result in response.Results: print "Error code for %s/%d is 0x%x" % ( str(ipaddress.ip_address(result.Prefix)), result.PrefixLen, result.ErrStatus.Status) os._exit(0)
def route_serializer(batch_info): """Agnostic function that returns either an IPv4 or IPv6 serializer instance. Not all fields are required to instantiate `SLRoutev4Msg`| `SLRoutev6Msg` classes. Therefore, conditions are specified to determine if certain keys exist within the dictionary parameters. If said keys do exist, then that attribute for the serializer class is assigned. Otherwise, fields are omitted, but the class is still instantiated. Returns: Tuple: sl_route_ipv4_pb2.SLRoutev4Msg|sl_route_ipv6_pb2.SLRoutev6Msg Next Prefix based on range value """ Message = collections.namedtuple('Message', [ 'af', 'serializer', 'route', ]) if batch_info['af'] == 4: # IPv4 message types. ipv4_or_ipv6 = Message(batch_info['af'], sl_route_ipv4_pb2.SLRoutev4Msg, sl_route_ipv4_pb2.SLRoutev4) elif batch_info['af'] == 6: # IPv6 message types. ipv4_or_ipv6 = Message(batch_info['af'], sl_route_ipv6_pb2.SLRoutev6Msg, sl_route_ipv6_pb2.SLRoutev6) # Create either a `SLRoutev4Msg` message or a `SLRoutev6Msg` # message. serializer = ipv4_or_ipv6.serializer() if 'vrf_name' in batch_info: serializer.VrfName = batch_info['vrf_name'] if 'correlator' in batch_info: serializer.Correlator = batch_info['correlator'] if 'routes' in batch_info: routes = [] for route in batch_info['routes']: # Create either a `SLRoutev4` message or a `SLRoutev6` # message. if 'local_label' in route: local_label = route['local_label'] r = ipv4_or_ipv6.route() if 'prefix' in route: addr = int(ipaddress.ip_address(route['prefix'])) if ipv4_or_ipv6.af == 4: r.Prefix = addr elif ipv4_or_ipv6.af == 6: r.Prefix = ipaddress.IPv6Address(addr).packed if 'prefix_len' in route: r.PrefixLen = route['prefix_len'] if 'admin_dist' in route: r.RouteCommon.AdminDistance = route['admin_dist'] if 'tag' in route: r.RouteCommon.Tag = route['tag'] if 'flags' in route: r.RouteCommon.Flags = route['flags'] ps = [] for path in route['path']: p = sl_route_common_pb2.SLRoutePath() nh = path['next_hop'] if ipv4_or_ipv6.af == 4: if 'v4_addr' in nh: p.NexthopAddress.V4Address = int( ipaddress.ip_address(nh['v4_addr'])) elif ipv4_or_ipv6.af == 6: if (nh and 'v6_addr' in nh): p.NexthopAddress.V6Address = ipaddress.ip_address( nh['v6_addr']).packed if 'if_name' in nh: p.NexthopInterface.Name = nh['if_name'] if 'load_metric' in path: p.LoadMetric = path['load_metric'] if 'metric' in path: p.Metric = path['metric'] if 'vrf_name' in nh: p.VrfName = nh['vrf_name'] if 'path_id' in path: p.PathId = path['path_id'] # Bitmap bitmap = [] if 'p_bitmap' in path: for bmap in path['p_bitmap']: bitmap.append(bmap) p.ProtectedPathBitmap.extend(bitmap) # Add labels labels = [] if 'labels' in path: for label in path['labels']: labels.append(label) p.LabelStack.extend(labels) # Add remote addresses remote_addr = [] if ipv4_or_ipv6.af == 4: if 'v4_remote_addr' in path: for r_addr in path['v4_remote_addr']: sl_r_addr = sl_common_types_pb2.SLIpAddress() sl_r_addr.V4Address = int( ipaddress.ip_address(r_addr)) remote_addr.append(sl_r_addr) p.RemoteAddress.extend(remote_addr) elif ipv4_or_ipv6.af == 6: if 'v6_remote_addr' in path: for r_addr in path['v6_remote_addr']: sl_r_addr = sl_common_types_pb2.SLIpAddress() sl_r_addr.V6Address = ipaddress.ip_address( r_addr).packed remote_addr.append(sl_r_addr) p.RemoteAddress.extend(remote_addr) # Append the `SLRoutePath` object to the `ps` list # object and extend the `sl_path_list` object of the # route. ps.append(p) r.PathList.extend(ps) # Append the `SLRoutev4`|`SLRoutev6` object to the `routes` # list object and extend the `sl_routes` object of the # serializer. routes.append(r) serializer.Routes.extend(routes) return serializer
def route_operation(channel, oper, loop_ip): # Create the gRPC stub. stub = sl_route_ipv4_pb2.beta_create_SLRoutev4Oper_stub(channel) # Create an empty list of routes. routeList = [] # Create the SLRoutev4Msg message holding the SLRoutev4 object list rtMsg = sl_route_ipv4_pb2.SLRoutev4Msg() rtMsg.VrfName = 'default' route = sl_route_ipv4_pb2.SLRoutev4() # IP Prefix route.Prefix = (int(ipaddress.ip_address(loop_ip[0]))) # Prefix Length route.PrefixLen = 32 # Administrative distance route.RouteCommon.AdminDistance = 0 paths = [] # Create an SLRoutePath path object. path = sl_route_common_pb2.SLRoutePath() # Fill in the path attributes. # Path next hop address path.NexthopAddress.V4Address = (int(ipaddress.ip_address(loop_ip[1]))) # Next hop interface name path.NexthopInterface.Name = loop_ip[2] # # Add the path to the list # paths.append(path) if oper != sl_common_types_pb2.SL_OBJOP_DELETE: route.PathList.extend(paths) # Append the route to the route list (bulk routes) routeList.append(route) # # Done building the routeList, assign it to the route message. # rtMsg.Routes.extend(routeList) # # Make an RPC call # Timeout = 10 # Seconds rtMsg.Oper = oper # Desired ADD, UPDATE, DELETE operation response = stub.SLRoutev4Op(rtMsg, Timeout) # # Check the received result from the Server # if (sl_common_types_pb2.SLErrorStatus.SL_SUCCESS == response.StatusSummary.Status): print "Route %s Success!" %( sl_common_types_pb2.SLObjectOp.keys()[oper]) else: print "Error code for route %s is 0x%x" % ( sl_common_types_pb2.SLObjectOp.keys()[oper], response.StatusSummary.Status ) # If we have partial failures within the batch, let's print them if (response.StatusSummary.Status == sl_common_types_pb2.SLErrorStatus.SL_SOME_ERR): for result in response.Results: print "Error code for %s/%d is 0x%x" %( str(ipaddress.ip_address(result.Prefix)), result.PrefixLen, result.ErrStatus.Status ) os._exit(0)