All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opendaylight.protocol.bgp.rib.impl.BGPSynchronization Maven / Gradle / Ivy

There is a newer version: 0.22.4
Show newest version
/*
 * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */
package org.opendaylight.protocol.bgp.rib.impl;

import static java.util.Objects.requireNonNull;

import com.google.common.annotations.VisibleForTesting;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.opendaylight.protocol.bgp.rib.spi.BGPSessionListener;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesReach;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesUnreach;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.UnicastSubsequentAddressFamily;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * BGP speaker (without Graceful restart capability) sends KeepAlive message after sending all initial Update messages
 * with certain AFI/SAFI. For each AFI/SAFI, it sends one KA message. As it is undetermined which KA message belongs to
 * which AFI/SAFI, an algorithm needed to be implemented.
 */
public class BGPSynchronization {

    private static final Logger LOG = LoggerFactory.getLogger(BGPSynchronization.class);

    @VisibleForTesting
    static class SyncVariables {

        private boolean upd = false;
        private boolean eor = false;

        public void setUpd(final boolean upd) {
            this.upd = upd;
        }

        public void setEorTrue() {
            eor = true;
        }

        public boolean getEor() {
            return eor;
        }

        public boolean getUpd() {
            return upd;
        }
    }

    @VisibleForTesting
    public final Map syncStorage = new HashMap<>();

    private final BGPSessionListener listener;

    public BGPSynchronization(final BGPSessionListener listener, final Set types) {
        this.listener = requireNonNull(listener);

        for (final TablesKey type : types) {
            syncStorage.put(type, new SyncVariables());
        }
    }

    /**
     * For each received Update message, the upd sync variable needs to be updated to true, for particular AFI/SAFI
     * combination. Currently we only assume Unicast SAFI. From the Update message we have to extract the AFI. Each
     * Update message can contain BGP Object with one type of AFI. If the object is BGP Link, BGP Node or a BGPPrefix
     * the AFI is Linkstate. In case of BGPRoute, the AFI depends on the IP Address of the prefix.
     *
     * @param msg received Update message
     */
    public void updReceived(final Update msg) {
        TablesKey type = new TablesKey(Ipv4AddressFamily.VALUE, UnicastSubsequentAddressFamily.VALUE);
        boolean isEOR = false;
        if (msg.getNlri() == null && msg.getWithdrawnRoutes() == null) {
            final Attributes attrs = msg.getAttributes();
            if (attrs != null) {
                if (attrs.augmentation(AttributesReach.class) != null) {
                    final AttributesReach pa = attrs.augmentation(AttributesReach.class);
                    if (pa.getMpReachNlri() != null) {
                        type = new TablesKey(pa.getMpReachNlri().getAfi(), pa.getMpReachNlri().getSafi());
                    }
                } else if (attrs.augmentation(AttributesUnreach.class) != null) {
                    final AttributesUnreach pa = attrs.augmentation(AttributesUnreach.class);
                    if (pa.getMpUnreachNlri() != null) {
                        type = new TablesKey(pa.getMpUnreachNlri().getAfi(), pa.getMpUnreachNlri().getSafi());
                    }
                    if (pa.getMpUnreachNlri().getWithdrawnRoutes() == null) {
                        // EOR message contains only MPUnreach attribute and no NLRI
                        isEOR = true;
                    }
                }
            } else {
                // true for empty Update Message
                isEOR = true;
            }
        }
        syncType(type, isEOR);
    }

    private void syncType(final TablesKey type, final boolean isEOR) {
        final SyncVariables s = syncStorage.get(type);
        if (s == null) {
            LOG.warn("BGPTableType was not present in open message : {}", type);
            return;
        }
        s.setUpd(true);
        if (isEOR) {
            s.setEorTrue();
            listener.markUptodate(type);
            LOG.info("BGP Synchronization finished for table {} ", type);
        }
    }

    /**
     * This method is called, when the second KA message is received. It checks each AFI/SAFI sync variables. If they
     * are all false, which means, that there was at least one update message followed by one KA, the EOR is sent to
     * session.
     */
    public void kaReceived() {
        for (final Entry entry : syncStorage.entrySet()) {
            final SyncVariables s = entry.getValue();
            if (!s.getEor()) {
                if (!s.getUpd()) {
                    s.setEorTrue();
                    LOG.info("BGP Synchronization finished for table {} ", entry.getKey());
                    listener.markUptodate(entry.getKey());
                }
                s.setUpd(false);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy