blob: 96756f5b999441f8742f6b2bccb3ed5233750916 [file] [log] [blame]
Zack Williams98725e22021-03-18 10:21:26 -07001#!/usr/bin/env python3
2
3# SPDX-FileCopyrightText: © 2021 Open Networking Foundation <support@opennetworking.org>
4# SPDX-License-Identifier: Apache-2.0
5
6# rfc3442_words.py
7# Input: a dict containing a router ip and multiple CIDR format routes
8# Output a list of octets to be appended to option 121 RFC3442 Classless routes option
9#
10# References:
11# https://tools.ietf.org/html/rfc3442
12# https://netaddr.readthedocs.io/en/latest/index.html
13
14from __future__ import absolute_import
15import netaddr
16
17
18class FilterModule(object):
19 def filters(self):
20 return {
21 "rfc3442_words": self.rfc3442_words,
22 }
23
24 def rfc3442_words(self, var):
25
26 words = []
27
28 router = var["ip"]
29 router_words = netaddr.IPNetwork(router).network.words
30
31 for r3442r in var["rfc3442routes"]:
32
33 # add prefix length
34 prefixlen = netaddr.IPNetwork(r3442r).prefixlen
35 words.append(prefixlen)
36
37 # add only the relevant portion of the address, depending ow words
38 (o1, o2, o3, o4) = netaddr.IPNetwork(r3442r).network.words
39 if prefixlen >= 25:
40 words += [o1, o2, o3, o4]
41 elif prefixlen >= 17:
42 words += [o1, o2, o3]
43 elif prefixlen >= 9:
44 words += [o1, o2]
45 elif prefixlen >= 1:
46 words += [o1]
47 # no additional words if prefixlen == 0
48
49 # add router address
50 words += list(router_words)
51
52 return words
53
54
55# test when running standalone outside of Ansible
56if __name__ == "__main__":
57
58 example = {
59 "ip": "192.168.1.10",
60 "rfc3442routes": [
61 "10.0.0.0/8",
62 "172.16.0.0/16",
63 "172.17.0.0/22",
64 "172.31.10.0/25",
65 ],
66 }
67
68 jfilter = FilterModule()
69
70 words = jfilter.rfc3442_words(example)
71
72 print(words)
73
74 # verify correct functionality
75 assert words == [
76 8, 10, 192, 168, 1, 10,
77 16, 172, 16, 192, 168, 1, 10,
78 22, 172, 17, 0, 192, 168, 1, 10,
79 25, 172, 31, 10, 0, 192, 168, 1, 10,
80 ]