<commit_before># Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from base import *

class BIRD(Container):
    def __init__(self, name, host_dir, guest_dir='/root/config', image='bgperf/bird'):
        super(BIRD, self).__init__(name, image, host_dir, guest_dir)

    @classmethod
    def build_image(cls, force=False, tag='bgperf/bird', checkout='HEAD', nocache=False):
        cls.dockerfile = '''
FROM ubuntu:latest
WORKDIR /root
RUN apt-get update && apt-get install -qy git autoconf libtool gawk make \
flex bison libncurses-dev libreadline6-dev
RUN apt-get install -qy flex
RUN git clone https://gitlab.labs.nic.cz/labs/bird.git bird && \
(cd bird && git checkout {0} && autoconf && ./configure && make && make install)
'''.format(checkout)
        super(BIRD, cls).build_image(force, tag, nocache)


    def write_config(self, conf, name='bird.conf'):
        config = '''router id {0};
listen bgp port 179;
protocol device {{ }}
protocol direct {{ disabled; }}
protocol kernel {{ disabled; }}
table master;
'''.format(conf['target']['router-id'])

        def gen_filter_assignment(n):
            if 'filter' in n:
                c = []
                if 'in' not in n['filter']:
                    c.append('import all;')
                else:
                    for p in n['filter']['in']:
                        c.append('import where {0}();'.format(p))

                if 'out' not in n['filter']:
                    c.append('export all;')
                else:
                    for p in n['filter']['out']:
                        c.append('export where {0}();'.format(p))
                return '\n'.join(c)
            return '''import all;
export all;
'''

        def gen_neighbor_config(n):
            return '''table table_{0};
protocol pipe pipe_{0} {{
    table master;
    mode transparent;
    peer table table_{0};
{3}
}}
protocol bgp bgp_{0} {{
    local as {1};
    neighbor {2} as {0};
    table table_{0};
    import all;
    export all;
    rs client;
}}
'''.format(n['as'], conf['target']['as'], n['local-address'].split('/')[0], gen_filter_assignment(n))

        def gen_prefix_filter(name, match):
            return '''function {0}()
prefix set prefixes;
{{
prefixes = [
{1}
];
if net ~ prefixes then return false;
return true;
}}
'''.format(name, ',\n'.join(match['value']))

        def gen_filter(name, match):
            c = ['function {0}()'.format(name), '{']
            for typ, name in match:
                c.append(' if ! {0}() then return false;'.format(name))
            c.append('return true;')
            c.append('}')
            return '\n'.join(c) + '\n'

        with open('{0}/{1}'.format(self.host_dir, name), 'w') as f:
            f.write(config)

            if 'policy' in conf:
                for k, v in conf['policy'].iteritems():
                    match_info = []
                    for i, match in enumerate(v['match']):
                        n = '{0}_match_{1}'.format(k, i)
                        if match['type'] == 'prefix':
                            f.write(gen_prefix_filter(n, match))
                        match_info.append((match['type'], n))
                    f.write(gen_filter(k, match_info))<commit_msg>bird.py: support as-path filter configuration<commit_after># Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from base import *

class BIRD(Container):
    def __init__(self, name, host_dir, guest_dir='/root/config', image='bgperf/bird'):
        super(BIRD, self).__init__(name, image, host_dir, guest_dir)

    @classmethod
    def build_image(cls, force=False, tag='bgperf/bird', checkout='HEAD', nocache=False):
        cls.dockerfile = '''
FROM ubuntu:latest
WORKDIR /root
RUN apt-get update && apt-get install -qy git autoconf libtool gawk make \
flex bison libncurses-dev libreadline6-dev
RUN apt-get install -qy flex
RUN git clone https://gitlab.labs.nic.cz/labs/bird.git bird && \
(cd bird && git checkout {0} && autoconf && ./configure && make && make install)
'''.format(checkout)
        super(BIRD, cls).build_image(force, tag, nocache)


    def write_config(self, conf, name='bird.conf'):
        config = '''router id {0};
listen bgp port 179;
protocol device {{ }}
protocol direct {{ disabled; }}
protocol kernel {{ disabled; }}
table master;
'''.format(conf['target']['router-id'])

        def gen_filter_assignment(n):
            if 'filter' in n:
                c = []
                if 'in' not in n['filter']:
                    c.append('import all;')
                else:
                    c.append('import where {0};'.format( '&&'.join(x + '()' for x in n['filter']['in'])))

                if 'out' not in n['filter']:
                    c.append('export all;')
                else:
                    c.append('export where {0};'.format( '&&'.join(x + '()' for x in n['filter']['out'])))

                return '\n'.join(c)
            return '''import all;
export all;
'''

        def gen_neighbor_config(n):
            return '''table table_{0};
protocol pipe pipe_{0} {{
    table master;
    mode transparent;
    peer table table_{0};
{3}
}}
protocol bgp bgp_{0} {{
    local as {1};
    neighbor {2} as {0};
    table table_{0};
    import all;
    export all;
    rs client;
}}
'''.format(n['as'], conf['target']['as'], n['local-address'].split('/')[0], gen_filter_assignment(n))

        def gen_prefix_filter(name, match):
            return '''function {0}()
prefix set prefixes;
{{
prefixes = [
{1}
];
if net ~ prefixes then return false;
return true;
}}
'''.format(name, ',\n'.join(match['value']))

        def gen_aspath_filter(name, match):
            c = '''function {0}()
{{
'''.format(name)
            c += '\n'.join('if (bgp_path ~ [= * {0} * =]) then return false;'.format(v) for v in match['value'])
            c += '''
return true;
}
'''
            return c

        def gen_filter(name, match):
            c = ['function {0}()'.format(name), '{']
            for typ, name in match:
                c.append(' if ! {0}() then return false;'.format(name))
            c.append('return true;')
            c.append('}')
            return '\n'.join(c) + '\n'

        with open('{0}/{1}'.format(self.host_dir, name), 'w') as f:
            f.write(config)

            if 'policy' in conf:
                for k, v in conf['policy'].iteritems():
                    match_info = []
                    for i, match in enumerate(v['match']):
                        n = '{0}_match_{1}'.format(k, i)
                        if match['type'] == 'prefix':
                            f.write(gen_prefix_filter(n, match))
                        elif match['type'] == 'as-path':
                            f.write(gen_aspath_filter(n, match))
                        match_info.append((match['type'], n))
                    f.write(gen_filter(k, match_info))
{'fraction_non_alphanumeric': 0.15175879396984926, 'fraction_numerical': 0.008793969849246231, 'mean_word_length': 2.2761316872427986, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2661064', 'n_tokens_mistral': 2429, 'n_tokens_neox': 2331, 'n_words': 709}