| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
| |
There are singline-line commands inside `router bgp` that start with
`vnc ` or `bmp `. Those commands are currently treated as node-entering
commands. We need to specify such commands more precisely.
Fixes #10548.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
|
|\
| |
| | |
tools: Stop disabled daemons when doing reload
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
After:
```
root@exit1-debian-11:~# grep ripngd= /etc/frr/daemons
ripngd=no
root@exit1-debian-11:~# pgrep -f ripngd -c
0
root@exit1-debian-11:~# sed -i 's/ripngd=no/ripngd=yes/' /etc/frr/daemons
root@exit1-debian-11:~# /usr/lib/frr/frrinit.sh reload
Stopped watchfrr.
Started watchfrr.
root@exit1-debian-11:~# pgrep -f ripngd -c
2
root@exit1-debian-11:~# grep ripngd= /etc/frr/daemons
ripngd=yes
root@exit1-debian-11:~# sed -i 's/ripngd=yes/ripngd=no/' /etc/frr/daemons
root@exit1-debian-11:~# /usr/lib/frr/frrinit.sh reload
Stopped watchfrr.
Started watchfrr.
Stopped ripngd.
root@exit1-debian-11:~# pgrep -f ripngd -c
0
```
Before:
```
root@exit1-debian-11:~# grep ripngd= /etc/frr/daemons
ripngd=no
root@exit1-debian-11:~# pgrep -f ripngd -c
0
root@exit1-debian-11:~# sed -i 's/ripngd=no/ripngd=yes/' /etc/frr/daemons
root@exit1-debian-11:~# /usr/lib/frr/frrinit.sh reload
Stopped watchfrr.
Started watchfrr.
root@exit1-debian-11:~# pgrep -f ripngd -c
2
root@exit1-debian-11:~# grep ripngd= /etc/frr/daemons
ripngd=yes
root@exit1-debian-11:~# sed -i 's/ripngd=yes/ripngd=no/' /etc/frr/daemons
root@exit1-debian-11:~# /usr/lib/frr/frrinit.sh reload
Stopped watchfrr.
Started watchfrr.
Stopped ripngd.
root@exit1-debian-11:~# pgrep -f ripngd -c
1 <<<<<< ripngd is running, while watchfrr skips it
```
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
|\ \
| | |
| | | |
doc: Add a commands snippet to workflow about what to do in RC1 phase
|
| | |
| | |
| | |
| | |
| | |
| | | |
What we should do when creating stabilization branch from the master.
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| | |
I think we don't care about this in release notes.
bgpd,pimd,isisd,nhrpd: Convert to vty_json() (origin/fix/vty_json)
ospf6d: Fix memory leak for `show ipv6 ospf6 zebra json` (origin/fix/zebra_ospf6d_json_leak)
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
|/
|
|
|
|
| |
Just to handle %s and %s\n.
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
|
|
|
|
|
|
|
|
|
|
| |
checkpatch.pl has a hardcoded list of printf extensions supported... by
the Linux kernel. This happens to have covered the ones we have in FRR
so far, but `%pPA` isn't on the list and others may not be either.
Since we have the frr-format GCC plugin (and CI runs that on Debian 11)
we don't really need these checks in checkpatch.pl.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
|
|\
| |
| | |
tools: cleanup convertion of "Null0"
|
| |
| |
| |
| | |
Signed-off-by: anlan_cs <anlan_cs@tom.com>
|
|\ \
| | |
| | | |
tools: fix wrong get_contexts() of Config class.
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Calling get_contexts() can't display as expected, it wrongly displays:
<__main__.Context object at 0x7fdee1d5ad50>
So make it display correct data by add __str__ in Context class.
Signed-off-by: anlan_cs <anlan_cs@tom.com>
|
|\ \ \
| | | |
| | | | |
build: add "--with-service-timeout" in configure.ac
|
| | |/
| |/|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
On lower CPU with lots of static routes, it will cost more than 2
minutes.
2 minutes is the default timeout value, we can adjust it by configure:
./configure --with-service-timeout=<digit>
Signed-off-by: anlan_cs <anlan_cs@tom.com>
|
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The generate_support_bundle.py script needs some
reformating to meet our standards
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
subprocess.check_call needs to be called with shell=True, else it will
interpret the string as a single path to execute instead of a command
with arguments:
Fixes the following error:
$ /usr/lib/frr/generate_support_bundle.py
Making backup of /var/log/frr/bgp_support_bundle.log
Traceback (most recent call last):
File "/usr/lib/frr/generate_support_bundle.py", line 89, in <module>
main()
File "/usr/lib/frr/generate_support_bundle.py", line 80, in main
stdout=open_with_backup(ofn),
File "/usr/lib/frr/generate_support_bundle.py", line 32, in open_with_backup
subprocess.check_call("mv {0} {0}.prev".format(path))
File "/usr/lib/python3.8/subprocess.py", line 359, in check_call
retcode = call(*popenargs, **kwargs)
File "/usr/lib/python3.8/subprocess.py", line 340, in call
with Popen(*popenargs, **kwargs) as p:
File "/usr/lib/python3.8/subprocess.py", line 858, in __init__
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/lib/python3.8/subprocess.py", line 1704, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'mv /var/log/frr/bgp_support_bundle.log /var/log/frr/bgp_support_bundle.log.prev'
Fixes: 5417cc2de ("tests: collect support bundle data in parallel, fix bugs")
Signed-off-by: Jonas Gorski <jonas.gorski@bisdn.de>
|
|\ \ |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This utility script helps in generated formatted and consistent
change log including:
1- group logs per daemon
2- standarize daemon names (lowercase, end with d)
3- capitalize all log lines
4- no merge commits
caveat: comments are assumed to be in the form
daemon-name : message
Sample Output:
```
sharpd
Follow the practice on cli design for json output
Install route supports nexthop-seg6 (step3)
Install_routes_helper support zapi_route flags (step1)
snapcraft
Add missing dependency
Add pathd to frr snap daemons
Change base to ubuntu 18.04 and libyang 2.0.7
staticd
Convert typedef to enum
Fix distance processing
Fix late initialization of blackhole type
Output config using nb callbacks instead of operational data
```
Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
|
|\ \ \
| | | |
| | | | |
tools: exit when reload fails to parse config file
|
| |/ /
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
frr-reload triggers restart of service in case
it fails to parse new config file and conjunction with
running config contains 'router bgp' (default bgp instnace).
When frr-reload fails to parse new config file, it fails
to build newconfig context (empty object).
Instead of bailing out it compares against the running config
context. If the running config contains default bgp instance
it thinks new config is removing default bgp instance so it
triggers frr restart.
Fix is to to bail out reload script when it fails to parse
config file.
Ticket:#2861989
Reviewed By: MR-83
Testing Done:
router bgp 102 vrf RED
bgp router-id 2.2.2.2
neighbor underlay peer-group
neighbor underlay remote-as <---- Partial config
Before fix:
2021-12-02 02:43:16,987 ERROR: vtysh failed to process new
configuration: vtysh (mark file) exited with status 4:
b'line 79: % Command incomplete: neighbor underlay remote-as\n\n'
2021-12-02 02:43:17,145 INFO: Loading Config object from vtysh show
running
2021-12-02 02:43:17,362 INFO: "frr version 7.5+cl5.0.0u0" cannot be
removed
2021-12-02 02:43:17,362 INFO: "frr defaults datacenter" cannot be
removed
2021-12-02 02:43:17,362 INFO: "service integrated-vtysh-config" cannot
be removed
2021-12-02 02:43:17,363 INFO: "line vty" cannot be removed
2021-12-02 02:43:17,522 INFO: EVPN is enabled and default instance del
needed
2021-12-02 02:43:17,522 INFO: Restarting FRR <---- Restart frr
After fix:
Just throw Error and abort the script.
root@TORS1:mgmt:/home/cumulus# /usr/lib/frr/frr-reload.py --debug
--reload --stdout /etc/frr/frr.conf
2021-12-02 04:00:56,519 INFO: Called via "Namespace(bindir='/usr/bin',
confdir='/etc/frr', daemon='', debug=True, filename='/etc/frr/$
rr.conf', input=None, overwrite=False, pathspace=None, reload=True,
rundir='/var/run/frr', stdout=True, test=False, vty_socket=None)"
2021-12-02 04:00:56,520 INFO: Loading Config object from file
/etc/frr/frr.conf
2021-12-02 04:00:56,679 ERROR: vtysh failed to process new
configuration: vtysh (mark file) exited with status 4:
b'line 79: % Command incomplete: neighbor underlay remote-as\n\n'
root@TORS1:mgmt:/home/cumulus#
Signed-off-by: Chirag Shah <chirag@nvidia.com>
|
|/ /
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Remove neighbor <> remote-as <> config line,
if the neighbor is part of the peer-group and
peer-group contains remote-as config.
Neighbors which are part of the peer-group
cannot override remote-as.
Fix:
Frr-reload needs to remote 'neighbor <> remote-as <>'
from lines_to_add if its already part of peer-group
and peer-group has remote-as config.
Testing Done:
Before:
Config snippet:
neighbor PEERS peer-group
neighbor PEERS remote-as external
neighbor PEERS timers 3 9
neighbor 10.2.1.1 remote-as external
neighbor 10.2.1.1 peer-group PEERS
neighbor 10.2.1.1 timers 3 9
neighbor 10.2.1.2 remote-as external
neighbor 10.2.1.2 peer-group PEERS
Frr-reload failure:
line 179: Failure to communicate[13] to bgpd, line: neighbor 10.2.1.1
remote-as external
% Peer-group member cannot override remote-as of peer-group
line 179: Failure to communicate[13] to bgpd, line: neighbor 10.2.1.2
remote-as external
% Peer-group member cannot override remote-as of peer-group
After:
frr-reload apply the config successfully.
Signed-off-by: Chirag Shah <chirag@nvidia.com>
|
|\ \ |
|
| | |
| | |
| | |
| | | |
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
|/ /
| |
| |
| | |
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
| |
| |
| |
| | |
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
| |
| |
| |
| |
| |
| |
| | |
This was deprecated over a year ago now. Let's finally
remove it from the system.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
|
| |
| |
| |
| |
| |
| | |
More memory leaks from libyang that we can just ignore
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
|
| |
| |
| |
| | |
Signed-off-by: Quentin Young <qlyoung@nvidia.com>
|
| |
| |
| |
| |
| |
| | |
Convert all floating string literals being used as comments, to comments
Signed-off-by: Quentin Young <qlyoung@nvidia.com>
|
| |
| |
| |
| |
| |
| |
| |
| | |
These aren't appropriate for use in FRR. Among other things, this
enables running checkpatch by calling it in a git working tree with
`tools/checkpatch.pl -g origin/master..`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
|
| |
| |
| |
| |
| |
| |
| | |
For the purpose of allowing the space in `frr_each (`, copy the list of
iterators from .clang-format and wire it up appropriately.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
|
| |
| |
| |
| |
| |
| |
| | |
Replaced single quotes with double quotes for strings in
the frr_babeltrace.py utility.
Signed-off-by: Anuradha Karuppiah <anuradhak@nvidia.com>
|
| |
| |
| |
| |
| |
| |
| | |
Make the script available as a part of the FRR package install for
ease of use.
Signed-off-by: Anuradha Karuppiah <anuradhak@nvidia.com>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
TPs -
=====
root@ibm-2410a1-01:mgmt:~# lttng list --userspace |grep frr_bgp:evpn.*recv
frr_bgp:evpn_local_l3vni_del_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_local_l3vni_add_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_local_macip_del_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_local_macip_add_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_local_vni_del_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_local_vni_add_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_mh_local_es_evi_del_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_mh_local_es_evi_add_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_mh_local_es_del_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_mh_local_es_add_zrecv (loglevel: TRACE_INFO (6)) (type: tracepoint)
root@ibm-2410a1-01:mgmt:~#
Sample output -
===============
1. ES
frr_bgp:evpn_mh_local_es_add_zrecv {'esi': '03:44:38:39:ff:ff:01:00:00:01', 'vtep': '27.0.0.15', 'active': 0, 'bypass': 0, 'df_pref': 50000}
frr_bgp:evpn_mh_local_es_del_zrecv {'esi': '03:44:38:39:ff:ff:01:00:00:01'}
2. ES-EVI
frr_bgp:evpn_mh_local_es_evi_add_zrecv {'esi': '03:44:38:39:ff:ff:01:00:00:01', 'vni': 1004}
frr_bgp:evpn_mh_local_es_evi_del_zrecv {'esi': '03:44:38:39:ff:ff:01:00:00:01', 'vni': 1001}
3. L2-VNI
frr_bgp:evpn_local_vni_add_zrecv {'vni': 1004, 'vtep': '27.0.0.15', 'mc_grp': '239.1.1.104', 'vrf': 97}
4. L3-VNI
frr_bgp:evpn_local_l3vni_add_zrecv {'vni': 4001, 'vrf': 87, 'svi_rmac': '24:8a:07:cc:aa:5f', 'vrr_rmac': '24:8a:07:cc:aa:5f', 'vtep': '27.0.0.15', 'filter': 0, 'svi_ifindex': 95, 'anycast_mac': 'n'
frr_bgp:evpn_local_l3vni_del_zrecv {'vni': 4003, 'vrf': 107}
5. MAC-IP
frr_bgp:evpn_local_macip_add_zrecv {'vni': 1003, 'mac': '00:02:00:00:00:04', 'ip': 'fe80::202:ff:fe00:4', 'flags': 4, 'seq': 0, 'esi': '03:44:38:39:ff:ff:01:00:00:02'}
frr_bgp:evpn_local_macip_del_zrecv {'vni': 1000, 'mac': '00:02:00:00:00:04', 'ip': '2001:fee1::4', 'state': 1}
Signed-off-by: Anuradha Karuppiah <anuradhak@nvidia.com>
|
|/
|
|
|
|
|
|
|
|
|
| |
```
% spatch --sp-file tools/coccinelle/struct_thread_double_pointer.cocci --macro-file tools/cocci.h ./ 2>/dev/null
./lib/northbound_confd.c:429:65-66: Passed double 'struct thread' pointer
./lib/northbound_confd.c:1174:61-62: Passed double 'struct thread' pointer
./lib/northbound_sysrepo.c:543:69-70: Passed double 'struct thread' pointer
```
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
|\
| |
| | |
cleanup: struct thread = NULL
|
| |
| |
| |
| | |
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
|/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Low overhead bgp-evpn TPs have been added which push data out in a binary
format -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
root@switch:~# lttng list --userspace |grep "frr_bgp:evpn"
frr_bgp:evpn_mh_nh_rmac_zsend (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
frr_bgp:evpn_mh_nh_zsend (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_mh_nhg_zsend (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_mh_vtep_zsend (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_bum_vtep_zsend (loglevel: TRACE_INFO (6)) (type: tracepoint)
frr_bgp:evpn_mac_ip_zsend (loglevel: TRACE_INFO (6)) (type: tracepoint)
root@switch:~#
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
In addition to the tracepoints a babeltrace python plugin for pretty
printing (binary data is converted into grepable strings). Sample usage -
frr_babeltrace.py trace_path
Sample tracepoint output -
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1. frr_bgp: evpn_mac_ip_zsend
frr_bgp:evpn_mac_ip_zsend {'action': 'add', 'vni': 1007, 'mac': '00:02:00:00:00:04', 'ip': 'fe80::202:ff:fe00:4', 'vtep': '27.0.0.15', 'esi': '03:44:38:39:ff:ff:01:00:00:02'}
2. frr_bgp: evpn_mh_vtep_zsend
frr_bgp:evpn_mh_vtep_zsend {'action': 'add', 'esi': '03:44:38:39:ff:ff:01:00:00:02', 'vtep': '27.0.0.16'}
3. frr_bgp: evpn_mh_nhg_zsend
frr_bgp:evpn_mh_nhg_zsend {'action': 'add', 'type': 'v4', 'nhg': 74999998, 'esi': '03:44:38:39:ff:ff:01:00:00:02', 'vrf': 85}
4. frr_bgp: evpn_mh_nh_zsend
frr_bgp:evpn_mh_nh_zsend {'nhg': 74999998, 'vtep': '27.0.0.16', 'svi': 93}
5. frr_bgp: evpn_mh_nh_rmac_zsend
frr_bgp:evpn_mh_nh_rmac_zsend {'action': 'add', 'vrf': 85, 'nh': '::ffff:1b00:12', 'rmac': '00:02:00:00:00:50'}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
Signed-off-by: Anuradha Karuppiah <anuradhak@nvidia.com>
|
|
|
|
| |
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
|
|
|
|
|
|
|
| |
Bunch of new stuff came in w/ the libyang2 upgrade that needs
to be suppressed. Make it so.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
|
|\ |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This allows defining a CLI command like this:
`[no] some setting ![VALUE]`
with VALUE being optional for the "no" form, but required for the
positive form. It's just a `[...]` where the empty branch can only be
taken for commands starting with `no`.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
|
| |
| |
| |
| | |
Signed-off-by: Christian Hopps <chopps@labn.net>
|
| |
| |
| |
| | |
Signed-off-by: Christian Hopps <chopps@labn.net>
|
| |
| |
| |
| |
| |
| |
| | |
We already, reasonably, require python3 elsewhere. Do so here, and reap some
benefit.
Signed-off-by: Christian Hopps <chopps@labn.net>
|
|\ \
| | |
| | | |
tools: fix frr pathspace folder permissions
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The pathspace folder in /var/run needs the x permission for the group too
Otherwise vtysh fails when running it with groups frrvty and frr:
$ vtysh -N gateway
% Can't open configuration file /etc/frr/gateway/vtysh.conf due to 'Permission denied'.
vtysh_connect(/var/run/frr/gateway/zebra.vty): stat = Permission denied
Signed-off-by: Steffen Neubauer <s.neubauer@syseleven.de>
|
| |/
|/|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Currently, in frr-reload we:
- store a list of single-line context keywords which needs to be
frequently updated,
- have a separate "if" clause for every node and subnode we have in FRR.
Instead, we can store the tree of all known FRR nodes. This tree needs
to be updated whenever we add a new node, which is not frequent. And,
most importantly, it allows us to write node-agnostic code and save more
than 250 LOC.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
|
|\ \
| | |
| | | |
tools: add ospfd support bundle commands
|
| | |
| | |
| | |
| | | |
Signed-off-by: Christian Hopps <chopps@labn.net>
|