api: split vl_api_prefix into two
One type for address with prefix and one type for prefix. Type: fix Signed-off-by: Ole Troan <ot@cisco.com> Change-Id: Icfec51d9b7d5cde1d69fbecdd97498688ab7b295 Signed-off-by: Ole Troan <ot@cisco.com> Signed-off-by: Klement Sekera <ksekera@cisco.com> Signed-off-by: Ole Troan <ot@cisco.com>
This commit is contained in:

committed by
Andrew Yourtchenko

parent
fbc388986e
commit
75761b933f
@ -39,7 +39,7 @@ autoreply manual_print define lb_conf
|
||||
autoreply manual_print define lb_add_del_vip {
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_prefix_t pfx;
|
||||
vl_api_address_with_prefix_t pfx;
|
||||
u8 protocol [default=255];
|
||||
u16 port;
|
||||
vl_api_lb_encap_type_t encap;
|
||||
@ -64,7 +64,7 @@ autoreply manual_print define lb_add_del_vip {
|
||||
autoreply manual_print define lb_add_del_as {
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_prefix_t pfx;
|
||||
vl_api_address_with_prefix_t pfx;
|
||||
u8 protocol [default=255];
|
||||
u16 port;
|
||||
vl_api_address_t as_address;
|
||||
@ -82,7 +82,7 @@ autoreply manual_print define lb_add_del_as {
|
||||
autoreply manual_print define lb_flush_vip {
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_prefix_t pfx;
|
||||
vl_api_address_with_prefix_t pfx;
|
||||
u8 protocol;
|
||||
u16 port;
|
||||
};
|
||||
@ -94,7 +94,7 @@ autoreply manual_print define lb_flush_vip {
|
||||
define lb_vip_dump{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
vl_api_prefix_t pfx;
|
||||
vl_api_address_with_prefix_t pfx;
|
||||
vl_api_prefix_matcher_t pfx_matcher;
|
||||
u8 protocol [default=255];
|
||||
u16 port;
|
||||
@ -126,7 +126,7 @@ define lb_as_dump{
|
||||
u32 client_index;
|
||||
u32 context;
|
||||
/* vip */
|
||||
vl_api_prefix_t pfx;
|
||||
vl_api_address_with_prefix_t pfx;
|
||||
u8 protocol;
|
||||
u16 port;
|
||||
};
|
||||
|
@ -67,7 +67,7 @@ enum lb_nat_protocol
|
||||
*/
|
||||
typedef lb_vip
|
||||
{
|
||||
vl_api_prefix_t pfx;
|
||||
vl_api_address_with_prefix_t pfx;
|
||||
vl_api_ip_proto_t protocol;
|
||||
u16 port;
|
||||
};
|
||||
|
@ -206,6 +206,9 @@ class Using():
|
||||
def __init__(self, name, flags, alias):
|
||||
self.name = name
|
||||
self.vla = False
|
||||
self.block = []
|
||||
self.manual_print = True
|
||||
self.manual_endian = True
|
||||
|
||||
self.manual_print = False
|
||||
self.manual_endian = False
|
||||
@ -750,7 +753,6 @@ class VPPAPI(object):
|
||||
s['Service'] = []
|
||||
s['types'] = []
|
||||
s['Import'] = []
|
||||
s['Alias'] = {}
|
||||
crc = 0
|
||||
for o in objs:
|
||||
tname = o.__class__.__name__
|
||||
@ -770,10 +772,9 @@ class VPPAPI(object):
|
||||
s['Service'].append(o2)
|
||||
elif (isinstance(o, Enum) or
|
||||
isinstance(o, Typedef) or
|
||||
isinstance(o, Using) or
|
||||
isinstance(o, Union)):
|
||||
s['types'].append(o)
|
||||
elif isinstance(o, Using):
|
||||
s['Alias'][o.name] = o
|
||||
else:
|
||||
if tname not in s:
|
||||
raise ValueError('Unknown class type: {} {}'
|
||||
|
@ -95,7 +95,7 @@ def api2c(fieldtype):
|
||||
return fieldtype
|
||||
|
||||
|
||||
def typedefs(objs, aliases, filename):
|
||||
def typedefs(objs, filename):
|
||||
name = filename.replace('.', '_')
|
||||
output = '''\
|
||||
|
||||
@ -108,16 +108,14 @@ def typedefs(objs, aliases, filename):
|
||||
'''
|
||||
output = output.format(module=name)
|
||||
|
||||
for k, v in aliases.items():
|
||||
if 'length' in v.alias:
|
||||
output += ('typedef %s vl_api_%s_t[%s];\n'
|
||||
% (v.alias['type'], k, v.alias['length']))
|
||||
else:
|
||||
output += 'typedef %s vl_api_%s_t;\n' % (v.alias['type'], k)
|
||||
|
||||
for o in objs:
|
||||
tname = o.__class__.__name__
|
||||
if tname == 'Enum':
|
||||
if tname == 'Using':
|
||||
if 'length' in o.alias:
|
||||
output += 'typedef %s vl_api_%s_t[%s];\n' % (o.alias['type'], o.name, o.alias['length'])
|
||||
else:
|
||||
output += 'typedef %s vl_api_%s_t;\n' % (o.alias['type'], o.name)
|
||||
elif tname == 'Enum':
|
||||
if o.enumtype == 'u32':
|
||||
output += "typedef enum {\n"
|
||||
else:
|
||||
@ -282,7 +280,7 @@ class Printfun():
|
||||
write(' return format(s, "{}", *a);\n'
|
||||
.format(format_strings[v.alias['type']]))
|
||||
else:
|
||||
write(' return format(s, "{} (print not implemented)"'
|
||||
write(' return format(s, "{} (print not implemented)");\n'
|
||||
.format(k))
|
||||
|
||||
def print_enum(self, o, stream):
|
||||
@ -357,7 +355,7 @@ static inline void *vl_api_{name}_t_print (vl_api_{name}_t *a, void *handle)
|
||||
return ''
|
||||
|
||||
|
||||
def printfun_types(objs, aliases, stream, modulename):
|
||||
def printfun_types(objs, stream, modulename):
|
||||
write = stream.write
|
||||
pp = Printfun(stream)
|
||||
|
||||
@ -380,15 +378,6 @@ static inline u8 *format_vl_api_{name}_t (u8 *s, va_list * args)
|
||||
indent += 2;
|
||||
'''
|
||||
|
||||
for k, v in aliases.items():
|
||||
if v.manual_print:
|
||||
write("/***** manual: vl_api_%s_t_print *****/\n\n" % k)
|
||||
continue
|
||||
|
||||
write(signature.format(name=k))
|
||||
pp.print_alias(k, v, stream)
|
||||
write('}\n\n')
|
||||
|
||||
for t in objs:
|
||||
if t.__class__.__name__ == 'Enum':
|
||||
write(signature.format(name=t.name))
|
||||
@ -401,6 +390,12 @@ static inline u8 *format_vl_api_{name}_t (u8 *s, va_list * args)
|
||||
write("/***** manual: vl_api_%s_t_print *****/\n\n" % t.name)
|
||||
continue
|
||||
|
||||
if t.__class__.__name__ == 'Using':
|
||||
write(signature.format(name=t.name))
|
||||
pp.print_alias(t.name, t, stream)
|
||||
write('}\n\n')
|
||||
continue
|
||||
|
||||
write(signature.format(name=t.name))
|
||||
for o in t.block:
|
||||
pp.print_obj(o, stream)
|
||||
@ -485,7 +480,7 @@ def endianfun_obj(o):
|
||||
return output
|
||||
|
||||
|
||||
def endianfun(objs, aliases, modulename):
|
||||
def endianfun(objs, modulename):
|
||||
output = '''\
|
||||
|
||||
/****** Endian swap functions *****/\n\
|
||||
@ -509,23 +504,6 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
|
||||
int i __attribute__((unused));
|
||||
'''
|
||||
|
||||
for k, v in aliases.items():
|
||||
if v.manual_endian:
|
||||
output += "/***** manual: vl_api_%s_t_endian *****/\n\n" % k
|
||||
continue
|
||||
|
||||
output += signature.format(name=k)
|
||||
if ('length' in v.alias and v.alias['length'] and
|
||||
v.alias['type'] == 'u8'):
|
||||
output += (' /* a->{name} = a->{name} (no-op) */\n'
|
||||
.format(name=k))
|
||||
elif v.alias['type'] in format_strings:
|
||||
output += (' *a = {}(*a);\n'
|
||||
.format(endian_strings[v.alias['type']]))
|
||||
else:
|
||||
output += ' /* Not Implemented yet {} */'.format(k)
|
||||
output += '}\n\n'
|
||||
|
||||
for t in objs:
|
||||
if t.__class__.__name__ == 'Enum':
|
||||
output += signature.format(name=t.name)
|
||||
@ -543,6 +521,21 @@ static inline void vl_api_{name}_t_endian (vl_api_{name}_t *a)
|
||||
output += "/***** manual: vl_api_%s_t_endian *****/\n\n" % t.name
|
||||
continue
|
||||
|
||||
|
||||
if t.__class__.__name__ == 'Using':
|
||||
output += signature.format(name=t.name)
|
||||
if ('length' in t.alias and t.alias['length'] and
|
||||
t.alias['type'] == 'u8'):
|
||||
output += (' /* a->{name} = a->{name} (no-op) */\n'
|
||||
.format(name=t.name))
|
||||
elif t.alias['type'] in format_strings:
|
||||
output += (' *a = {}(*a);\n'
|
||||
.format(endian_strings[t.alias['type']]))
|
||||
else:
|
||||
output += ' /* Not Implemented yet {} */'.format(t.name)
|
||||
output += '}\n\n'
|
||||
continue
|
||||
|
||||
output += signature.format(name=t.name)
|
||||
|
||||
for o in t.block:
|
||||
@ -588,12 +581,11 @@ def run(input_filename, s):
|
||||
output += msg_ids(s)
|
||||
output += msg_names(s)
|
||||
output += msg_name_crc_list(s, filename)
|
||||
output += typedefs(s['types'] + s['Define'], s['Alias'],
|
||||
filename + file_extension)
|
||||
printfun_types(s['types'], s['Alias'], stream, modulename)
|
||||
output += typedefs(s['types'] + s['Define'], filename + file_extension)
|
||||
printfun_types(s['types'], stream, modulename)
|
||||
printfun(s['Define'], stream, modulename)
|
||||
output += stream.getvalue()
|
||||
output += endianfun(s['types'] + s['Define'], s['Alias'], modulename)
|
||||
output += endianfun(s['types'] + s['Define'], modulename)
|
||||
output += version_tuple(s, basename)
|
||||
output += bottom_boilerplate.format(input_filename=basename,
|
||||
file_crc=s['file_crc'])
|
||||
|
@ -58,7 +58,6 @@ def walk_defs(s, is_message=False):
|
||||
r.append(d)
|
||||
return r
|
||||
|
||||
|
||||
#
|
||||
# Plugin entry point
|
||||
#
|
||||
@ -74,6 +73,6 @@ def run(filename, s):
|
||||
if o.__class__.__name__ == 'Enum']))
|
||||
j['services'] = walk_services(s['Service'])
|
||||
j['options'] = s['Option']
|
||||
j['aliases'] = {k: v.alias for k, v in s['Alias'].items()}
|
||||
j['aliases'] = {o.name:o.alias for o in s['types'] if o.__class__.__name__ == 'Using'}
|
||||
j['vl_api_version'] = hex(s['file_crc'])
|
||||
return json.dumps(j, indent=4, separators=(',', ': '))
|
||||
|
@ -223,7 +223,7 @@ autoreply define sw_interface_add_del_address
|
||||
bool is_add;
|
||||
|
||||
bool del_all;
|
||||
vl_api_prefix_t prefix;
|
||||
vl_api_address_with_prefix_t prefix;
|
||||
};
|
||||
|
||||
/** \brief Associate the specified interface with a fib table
|
||||
|
@ -29,7 +29,7 @@ import "vnet/mfib/mfib_types.api";
|
||||
/** \brief An IP table
|
||||
@param is_ipv6 - V4 or V6 table
|
||||
@param table_id - table ID associated with the route
|
||||
This table ID will apply to both the unicats
|
||||
This table ID will apply to both the unicats
|
||||
and mlticast FIBs
|
||||
@param name - A client provided name/tag for the table. If this is
|
||||
not set by the client, then VPP will generate something
|
||||
@ -496,7 +496,7 @@ define ip_address_details
|
||||
{
|
||||
u32 context;
|
||||
u32 sw_if_index;
|
||||
vl_api_prefix_t prefix;
|
||||
vl_api_address_with_prefix_t prefix;
|
||||
};
|
||||
|
||||
define ip_address_dump
|
||||
|
@ -83,4 +83,10 @@ format_vl_api_prefix_t (u8 * s, va_list * args)
|
||||
return format (s, "%U/%u", format_vl_api_address_t, &a->address, indent, a->len);
|
||||
}
|
||||
|
||||
static inline u8 *
|
||||
format_vl_api_address_with_prefix_t (u8 * s, va_list * args)
|
||||
{
|
||||
return format_vl_api_prefix_t (s, args);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -108,6 +108,23 @@ manual_print typedef ip4_prefix {
|
||||
u8 len;
|
||||
};
|
||||
|
||||
/** \brief
|
||||
*
|
||||
* The vl_api_[ip4|ip6]_address_with_prefix_t types are used as a type to denote
|
||||
* both an IP address and a prefix. I.e. in CIDR notation
|
||||
* '192.168.10.1/24' the address is 192.168.10.1 and the network
|
||||
* prefix is 192.168.10.0/24.
|
||||
*
|
||||
* If only an address is needed use: vl_api_address_t types and if
|
||||
* only a network prefix is needed (i.e. no hosts bits), then use the
|
||||
* vl_api_prefix_t types.
|
||||
*
|
||||
**/
|
||||
|
||||
manual_print typedef vl_api_prefix_t address_with_prefix;
|
||||
manual_print typedef vl_api_ip4_prefix_t ip4_address_with_prefix;
|
||||
manual_print typedef vl_api_ip6_prefix_t ip6_address_with_prefix;
|
||||
|
||||
/** \brief A context for matching prefixes against. (Think ip prefix list.)
|
||||
The meaning (exact match / want subnets) of an unset matcher is left to the implementer.
|
||||
@param le - le mut be <= to prefix.len. Default: 255 (not set).
|
||||
|
@ -26,8 +26,7 @@ import "vnet/ip/ip_types.api";
|
||||
@param mb_ip_table_id - The IP table-id of the IP prefix to bind to.
|
||||
@param mb_is_bind - Bind or unbind
|
||||
@param mb_is_ip4 - The prefix to bind to is IPv4
|
||||
@param mb_address_length - Length of IP prefix
|
||||
@param mb_address[16] - IP prefix/
|
||||
@param mb_prefix - IP prefix
|
||||
*/
|
||||
autoreply define mpls_ip_bind_unbind
|
||||
{
|
||||
|
@ -104,6 +104,10 @@ class TestAddType(unittest.TestCase):
|
||||
[['vl_api_address_family_t', 'af'],
|
||||
['vl_api_address_union_t', 'un']])
|
||||
|
||||
prefix = VPPType('vl_api_prefix_t',
|
||||
[['vl_api_address_t', 'address'],
|
||||
['u8', 'len']])
|
||||
|
||||
va_address_list = VPPType('list_addresses',
|
||||
[['u8', 'count'],
|
||||
['vl_api_address_t', 'addresses',
|
||||
@ -151,6 +155,96 @@ class TestAddType(unittest.TestCase):
|
||||
nt, size = message_with_va_address_list.unpack(b)
|
||||
self.assertEqual(nt.is_cool, 100)
|
||||
|
||||
def test_address_with_prefix(self):
|
||||
af = VPPEnumType('vl_api_address_family_t', [["ADDRESS_IP4", 0],
|
||||
["ADDRESS_IP6", 1],
|
||||
{"enumtype": "u32"}])
|
||||
ip4 = VPPTypeAlias('vl_api_ip4_address_t', {'type': 'u8',
|
||||
'length': 4})
|
||||
ip6 = VPPTypeAlias('vl_api_ip6_address_t', {'type': 'u8',
|
||||
'length': 16})
|
||||
VPPUnionType('vl_api_address_union_t',
|
||||
[["vl_api_ip4_address_t", "ip4"],
|
||||
["vl_api_ip6_address_t", "ip6"]])
|
||||
|
||||
address = VPPType('vl_api_address_t',
|
||||
[['vl_api_address_family_t', 'af'],
|
||||
['vl_api_address_union_t', 'un']])
|
||||
|
||||
|
||||
prefix = VPPType('vl_api_prefix_t',
|
||||
[['vl_api_address_t', 'address'],
|
||||
['u8', 'len']])
|
||||
prefix4 = VPPType('vl_api_ip4_prefix_t',
|
||||
[['vl_api_ip4_address_t', 'address'],
|
||||
['u8', 'len']])
|
||||
prefix6 = VPPType('vl_api_ip6_prefix_t',
|
||||
[['vl_api_ip6_address_t', 'address'],
|
||||
['u8', 'len']])
|
||||
|
||||
address_with_prefix = VPPTypeAlias('vl_api_address_with_prefix_t', {'type': 'vl_api_prefix_t' })
|
||||
address4_with_prefix = VPPTypeAlias('vl_api_ip4_address_with_prefix_t',
|
||||
{'type': 'vl_api_ip4_prefix_t' })
|
||||
address6_with_prefix = VPPTypeAlias('vl_api_ip6_address_with_prefix_t',
|
||||
{'type': 'vl_api_ip6_prefix_t' })
|
||||
|
||||
awp_type = VPPType('foobar_t',
|
||||
[['vl_api_address_with_prefix_t', 'address']])
|
||||
|
||||
# address with prefix
|
||||
b = address_with_prefix.pack(IPv4Interface('2.2.2.2/24'))
|
||||
self.assertEqual(len(b), 21)
|
||||
nt, size = address_with_prefix.unpack(b)
|
||||
self.assertTrue(isinstance(nt, IPv4Interface))
|
||||
self.assertEqual(str(nt), '2.2.2.2/24')
|
||||
|
||||
b = address_with_prefix.pack(IPv6Interface('2::2/64'))
|
||||
self.assertEqual(len(b), 21)
|
||||
nt, size = address_with_prefix.unpack(b)
|
||||
self.assertTrue(isinstance(nt, IPv6Interface))
|
||||
self.assertEqual(str(nt), '2::2/64')
|
||||
|
||||
b = address_with_prefix.pack(IPv4Network('2.2.2.2/24', strict=False))
|
||||
self.assertEqual(len(b), 21)
|
||||
nt, size = address_with_prefix.unpack(b)
|
||||
self.assertTrue(isinstance(nt, IPv4Interface))
|
||||
self.assertEqual(str(nt), '2.2.2.0/24')
|
||||
|
||||
b = address4_with_prefix.pack('2.2.2.2/24')
|
||||
self.assertEqual(len(b), 5)
|
||||
nt, size = address4_with_prefix.unpack(b)
|
||||
self.assertTrue(isinstance(nt, IPv4Interface))
|
||||
self.assertEqual(str(nt), '2.2.2.2/24')
|
||||
b = address4_with_prefix.pack(IPv4Interface('2.2.2.2/24'))
|
||||
self.assertEqual(len(b), 5)
|
||||
|
||||
b = address6_with_prefix.pack('2::2/64')
|
||||
self.assertEqual(len(b), 17)
|
||||
nt, size = address6_with_prefix.unpack(b)
|
||||
self.assertTrue(isinstance(nt, IPv6Interface))
|
||||
self.assertEqual(str(nt), '2::2/64')
|
||||
b = address6_with_prefix.pack(IPv6Interface('2::2/64'))
|
||||
self.assertEqual(len(b), 17)
|
||||
|
||||
b = prefix.pack('192.168.10.0/24')
|
||||
self.assertEqual(len(b), 21)
|
||||
nt, size = prefix.unpack(b)
|
||||
self.assertTrue(isinstance(nt, IPv4Network))
|
||||
self.assertEqual(str(nt), '192.168.10.0/24')
|
||||
|
||||
b = awp_type.pack({'address': '1.2.3.4/24'})
|
||||
self.assertEqual(len(b), 21)
|
||||
nt, size = awp_type.unpack(b)
|
||||
self.assertTrue(isinstance(nt.address, IPv4Interface))
|
||||
self.assertEqual(str(nt.address), '1.2.3.4/24')
|
||||
|
||||
b = awp_type.pack({'address': IPv4Interface('1.2.3.4/24')})
|
||||
self.assertEqual(len(b), 21)
|
||||
nt, size = awp_type.unpack(b)
|
||||
self.assertTrue(isinstance(nt.address, IPv4Interface))
|
||||
self.assertEqual(str(nt.address), '1.2.3.4/24')
|
||||
|
||||
|
||||
def test_recursive_address(self):
|
||||
af = VPPEnumType('vl_api_address_family_t', [["ADDRESS_IP4", 0],
|
||||
["ADDRESS_IP6", 1],
|
||||
|
@ -52,6 +52,15 @@ def format_vl_api_prefix_t(args):
|
||||
return {'address': format_vl_api_address_t(p),
|
||||
'len': int(length)}
|
||||
|
||||
def format_vl_api_address_with_prefix_t(args):
|
||||
if isinstance(args, (ipaddress.IPv4Interface, ipaddress.IPv6Interface)):
|
||||
return {'address': format_vl_api_address_t(
|
||||
text_type(args.network_address)),
|
||||
'len': int(args.prefixlen)}
|
||||
p, length = args.split('/')
|
||||
return {'address': format_vl_api_address_t(p),
|
||||
'len': int(length)}
|
||||
|
||||
|
||||
def format_vl_api_ip6_prefix_t(args):
|
||||
if isinstance(args, ipaddress.IPv6Network):
|
||||
@ -61,6 +70,13 @@ def format_vl_api_ip6_prefix_t(args):
|
||||
return {'address': inet_pton(AF_INET6, p),
|
||||
'len': int(length)}
|
||||
|
||||
def format_vl_api_ip6_address_with_prefix_t(args):
|
||||
if isinstance(args, ipaddress.IPv6Interface):
|
||||
return {'address': args.network_address.packed,
|
||||
'len': int(args.prefixlen)}
|
||||
p, length = args.split('/')
|
||||
return {'address': inet_pton(AF_INET6, p),
|
||||
'len': int(length)}
|
||||
|
||||
def format_vl_api_ip4_prefix_t(args):
|
||||
if isinstance(args, ipaddress.IPv4Network):
|
||||
@ -70,6 +86,14 @@ def format_vl_api_ip4_prefix_t(args):
|
||||
return {'address': inet_pton(AF_INET, p),
|
||||
'len': int(length)}
|
||||
|
||||
def format_vl_api_ip4_address_with_prefix_t(args):
|
||||
if isinstance(args, ipaddress.IPv4Interface):
|
||||
return {'address': args.network_address.packed,
|
||||
'len': int(args.prefixlen)}
|
||||
p, length = args.split('/')
|
||||
return {'address': inet_pton(AF_INET, p),
|
||||
'len': int(length)}
|
||||
|
||||
|
||||
conversion_table = {
|
||||
'vl_api_ip6_address_t':
|
||||
@ -112,6 +136,30 @@ conversion_table = {
|
||||
'len': o.prefixlen},
|
||||
'str': lambda s: format_vl_api_prefix_t(s)
|
||||
},
|
||||
'vl_api_address_with_prefix_t':
|
||||
{
|
||||
'IPv4Interface': lambda o: {'address':
|
||||
{'af': ADDRESS_IP4, 'un':
|
||||
{'ip4': o.packed}},
|
||||
'len': o.network.prefixlen},
|
||||
'IPv6Interface': lambda o: {'address':
|
||||
{'af': ADDRESS_IP6, 'un':
|
||||
{'ip6': o.packed}},
|
||||
'len': o.network.prefixlen},
|
||||
'str': lambda s: format_vl_api_address_with_prefix_t(s)
|
||||
},
|
||||
'vl_api_ip4_address_with_prefix_t':
|
||||
{
|
||||
'IPv4Interface': lambda o: {'address': o.packed,
|
||||
'len': o.network.prefixlen},
|
||||
'str': lambda s: format_vl_api_ip4_address_with_prefix_t(s)
|
||||
},
|
||||
'vl_api_ip6_address_with_prefix_t':
|
||||
{
|
||||
'IPv6Interface': lambda o: {'address': o.packed,
|
||||
'len': o.network.prefixlen},
|
||||
'str': lambda s: format_vl_api_ip6_address_with_prefix_t(s)
|
||||
},
|
||||
'vl_api_mac_address_t':
|
||||
{
|
||||
'MACAddress': lambda o: o.packed,
|
||||
@ -130,14 +178,33 @@ def unformat_api_address_t(o):
|
||||
return ipaddress.IPv6Address(o.un.ip6)
|
||||
if o.af == 0:
|
||||
return ipaddress.IPv4Address(o.un.ip4)
|
||||
|
||||
raise ValueError('Unknown address family {}'.format(o))
|
||||
|
||||
def unformat_api_prefix_t(o):
|
||||
if o.address.af == 1:
|
||||
return ipaddress.IPv6Network((o.address.un.ip6, o.len), False)
|
||||
if o.address.af == 0:
|
||||
return ipaddress.IPv4Network((o.address.un.ip4, o.len), False)
|
||||
raise ValueError('Unknown address family {}'.format(o))
|
||||
|
||||
if isinstance(o.address, ipaddress.IPv4Address):
|
||||
return ipaddress.IPv4Network((o.address, o.len), False)
|
||||
if isinstance(o.address, ipaddress.IPv6Address):
|
||||
return ipaddress.IPv6Network((o.address, o.len), False)
|
||||
raise ValueError('Unknown instance {}', format(o))
|
||||
|
||||
def unformat_api_address_with_prefix_t(o):
|
||||
if o.address.af == 1:
|
||||
return ipaddress.IPv6Interface((o.address.un.ip6, o.len))
|
||||
if o.address.af == 0:
|
||||
return ipaddress.IPv4Interface((o.address.un.ip4, o.len))
|
||||
raise ValueError('Unknown address family {}'.format(o))
|
||||
|
||||
def unformat_api_ip4_address_with_prefix_t(o):
|
||||
return ipaddress.IPv4Interface((o.address, o.len))
|
||||
|
||||
def unformat_api_ip6_address_with_prefix_t(o):
|
||||
return ipaddress.IPv6Interface((o.address, o.len))
|
||||
|
||||
conversion_unpacker_table = {
|
||||
'vl_api_ip6_address_t': lambda o: ipaddress.IPv6Address(o),
|
||||
@ -146,6 +213,9 @@ conversion_unpacker_table = {
|
||||
'vl_api_ip4_prefix_t': lambda o: ipaddress.IPv4Network((o.address, o.len)),
|
||||
'vl_api_address_t': lambda o: unformat_api_address_t(o),
|
||||
'vl_api_prefix_t': lambda o: unformat_api_prefix_t(o),
|
||||
'vl_api_address_with_prefix_t': lambda o: unformat_api_address_with_prefix_t(o),
|
||||
'vl_api_ip4_address_with_prefix_t': lambda o: unformat_api_ip4_address_with_prefix_t(o),
|
||||
'vl_api_ip6_address_with_prefix_t': lambda o: unformat_api_ip6_address_with_prefix_t(o),
|
||||
'vl_api_mac_address_t': lambda o: macaddress.MACAddress(o),
|
||||
'vl_api_timestamp_t': lambda o: datetime.datetime.fromtimestamp(o),
|
||||
'vl_api_timedelta_t': lambda o: datetime.timedelta(seconds=o),
|
||||
|
@ -414,7 +414,7 @@ class VPPTypeAlias(object):
|
||||
self.name = name
|
||||
t = vpp_get_type(msgdef['type'])
|
||||
if not t:
|
||||
raise ValueError()
|
||||
raise ValueError('No such type: {}'.format(msgdef['type']))
|
||||
if 'length' in msgdef:
|
||||
if msgdef['length'] == 0:
|
||||
raise ValueError()
|
||||
@ -429,6 +429,7 @@ class VPPTypeAlias(object):
|
||||
self.size = t.size
|
||||
|
||||
types[name] = self
|
||||
self.toplevelconversion = False
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
@ -445,8 +446,13 @@ class VPPTypeAlias(object):
|
||||
return self.packer.pack(data, kwargs)
|
||||
|
||||
def unpack(self, data, offset=0, result=None, ntc=False):
|
||||
if ntc == False and self.name in vpp_format.conversion_unpacker_table:
|
||||
# Disable type conversion for dependent types
|
||||
ntc = True
|
||||
self.toplevelconversion = True
|
||||
t, size = self.packer.unpack(data, offset, result, ntc=ntc)
|
||||
if not ntc:
|
||||
if self.toplevelconversion:
|
||||
self.toplevelconversion = False
|
||||
return conversion_unpacker(t, self.name), size
|
||||
return t, size
|
||||
|
||||
@ -513,6 +519,7 @@ class VPPType(object):
|
||||
self.size = size
|
||||
self.tuple = collections.namedtuple(name, self.fields, rename=True)
|
||||
types[name] = self
|
||||
self.toplevelconversion = False
|
||||
|
||||
def __call__(self, args):
|
||||
self.options = args
|
||||
@ -551,6 +558,11 @@ class VPPType(object):
|
||||
# Return a list of arguments
|
||||
result = []
|
||||
total = 0
|
||||
if ntc == False and self.name in vpp_format.conversion_unpacker_table:
|
||||
# Disable type conversion for dependent types
|
||||
ntc = True
|
||||
self.toplevelconversion = True
|
||||
|
||||
for p in self.packers:
|
||||
x, size = p.unpack(data, offset, result, ntc)
|
||||
if type(x) is tuple and len(x) == 1:
|
||||
@ -559,7 +571,9 @@ class VPPType(object):
|
||||
offset += size
|
||||
total += size
|
||||
t = self.tuple._make(result)
|
||||
if not ntc:
|
||||
|
||||
if self.toplevelconversion:
|
||||
self.toplevelconversion = False
|
||||
t = conversion_unpacker(t, self.name)
|
||||
return t, total
|
||||
|
||||
|
@ -713,12 +713,12 @@ def gen_json_unified_header(parser, logger, j, io, name):
|
||||
emitted = []
|
||||
for e in parser.enums_by_json[j]:
|
||||
emit_definition(parser, j, emitted, e)
|
||||
for a in parser.aliases_by_json[j]:
|
||||
emit_definition(parser, j, emitted, a)
|
||||
for u in parser.unions_by_json[j]:
|
||||
emit_definition(parser, j, emitted, u)
|
||||
for t in parser.types_by_json[j]:
|
||||
emit_definition(parser, j, emitted, t)
|
||||
for a in parser.aliases_by_json[j]:
|
||||
emit_definition(parser, j, emitted, a)
|
||||
for m in parser.messages_by_json[j].values():
|
||||
emit_definition(parser, j, emitted, m)
|
||||
|
||||
|
@ -377,19 +377,6 @@ class JsonParser(object):
|
||||
self.unions[union.name] = union
|
||||
self.logger.debug("Parsed union: %s" % union)
|
||||
self.unions_by_json[path].append(union)
|
||||
for name, body in j['aliases'].iteritems():
|
||||
if name in self.aliases:
|
||||
progress = progress + 1
|
||||
continue
|
||||
if 'length' in body:
|
||||
array_len = body['length']
|
||||
else:
|
||||
array_len = None
|
||||
t = self.types[body['type']]
|
||||
alias = self.alias_class(name, t, array_len)
|
||||
self.aliases[name] = alias
|
||||
self.logger.debug("Parsed alias: %s" % alias)
|
||||
self.aliases_by_json[path].append(alias)
|
||||
for t in j['types']:
|
||||
if t[0] in self.types:
|
||||
progress = progress + 1
|
||||
@ -408,6 +395,23 @@ class JsonParser(object):
|
||||
self.types[type_.name] = type_
|
||||
self.types_by_json[path].append(type_)
|
||||
self.logger.debug("Parsed type: %s" % type_)
|
||||
for name, body in j['aliases'].iteritems():
|
||||
if name in self.aliases:
|
||||
progress = progress + 1
|
||||
continue
|
||||
if 'length' in body:
|
||||
array_len = body['length']
|
||||
else:
|
||||
array_len = None
|
||||
try:
|
||||
t = self.lookup_type_like_id(body['type'])
|
||||
except ParseError as e:
|
||||
exceptions.append(e)
|
||||
continue
|
||||
alias = self.alias_class(name, t, array_len)
|
||||
self.aliases[name] = alias
|
||||
self.logger.debug("Parsed alias: %s" % alias)
|
||||
self.aliases_by_json[path].append(alias)
|
||||
if not exceptions:
|
||||
# finished parsing
|
||||
break
|
||||
|
@ -153,7 +153,7 @@ def fib_interface_ip_prefix(test, address, length, sw_if_index):
|
||||
# TODO: refactor this to VppIpPrefix.__eq__
|
||||
for a in addrs:
|
||||
if a.sw_if_index == sw_if_index and \
|
||||
a.prefix == prefix:
|
||||
a.prefix.network == prefix:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
Reference in New Issue
Block a user