Support for TCP MD5 Signature Option configuration of Quagga BGP

This functionality adds support to odl-netvirt-impl feature to configure the TCP MD5 Signature Option [RFC2385] password in Quagga BGPs [QBGP].

Problem description

Quagga [QBGP] supports TCP MD5 Signature Option [RFC2385] in BGP traffic but current odl-netvirt-impl feature implementation lacks support to configure the required passwords.

Use Cases

UC1: Protect (Quagga [QBGP]) BGP and DC gateway BGP interface using TCP MD5 Signature Option [RFC2385].

Proposed change

The following components need to be enhanced:

  • BGP Manager

Pipeline changes

No pipeline changes.

API changes

Changes will be needed in ebgp.yang, and qbgp.thrift.

YANG changes

A new optional leaf with the TCP MD5 Signature Option [RFC2385] password is added (by means of a choice) to list neighbors.

ebgp.yang additions
typedef tcp-md5-signature-password-type {
  type string {
    length 1..80;
  } // subtype string
    "The shared secret used by TCP MD5 Signature Option.  The length is
     limited to 80 chars because A) it is identified by the RFC as current
     practice and B) it is the maximum length accepted by Quagga
  reference "RFC 2385";
} // typedef tcp-md5-signature-password-type

grouping tcp-security-option-grouping {
  description "TCP security options.";
  choice tcp-security-option {
    description "The tcp security option in use, if any.";

    case tcp-md5-signature-option {
      description "The connection uses TCP MD5 Signature Option.";
      reference "RFC 2385";
      leaf tcp-md5-signature-password {
        type tcp-md5-signature-password-type;
        description "The shared secret used to sign the packets.";
      } // leaf tcp-md5-signature-password
    } // case tcp-md5-signature-option

  } // choice tcp-security-option
} // grouping tcp-security-option-grouping
ebgp.yang modifications
    list neighbors {
      key "address";
      leaf address {
        type inet:ipv4-address;
        mandatory "true";
      leaf remote-as {
        type uint32;
        mandatory "true";
 +    use tcp-security-option-grouping;

Thrift changes

A new function setPeerSecret is added to the service BgpConfigurator.

qbgp.thrift modifications
--- a/vpnservice/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/netvirt/bgpmanager/thrift/idl/qbgp.thrift
+++ b/vpnservice/bgpmanager/bgpmanager-impl/src/main/java/org/opendaylight/netvirt/bgpmanager/thrift/idl/qbgp.thrift
@@ -31,6 +31,8 @@ const i32 GET_RTS_NEXT = 1
  * ERR_NOT_ITER when GET_RTS_NEXT is called without
  *    initializing with GET_RTS_INIT
  * ERR_PARAM when there is an issue with params
+ * ERR_NOT_SUPPORTED when the server does not support
+ *    the operation.

 const i32 BGP_ERR_FAILED = 1
@@ -38,6 +40,7 @@ const i32 BGP_ERR_ACTIVE = 10
 const i32 BGP_ERR_INACTIVE = 11
 const i32 BGP_ERR_NOT_ITER = 15
 const i32 BGP_ERR_PARAM = 100
+const i32 BGP_ERR_NOT_SUPPORTED = 200

 // these are the supported afi-safi combinations
 enum af_afi {
@@ -122,6 +125,33 @@ service BgpConfigurator {
                        6:i32 stalepathTime, 7:bool announceFlush),
     i32 stopBgp(1:i64 asNumber),
     i32 createPeer(1:string ipAddress, 2:i64 asNumber),
+    /* 'setPeerSecret' sets the shared secret needed to protect the peer
+     * connection using TCP MD5 Signature Option (see rfc 2385).
+     *
+     * Params:
+     *
+     *   'ipAddress' is the peer (neighbour) address.  Mandatory.
+     *
+     *   'rfc2385_sharedSecret' is the secret.  Mandatory.  Length must be
+     *   greater than zero.
+     *
+     * Return codes:
+     *
+     *   0 on success.
+     *
+     *   BGP_ERR_FAILED if 'ipAddress' is missing or unknown.
+     *
+     *   BGP_ERR_PARAM if 'rfc2385_sharedSecret' is missing or invalid (e.g.
+     *   it is too short or too long).
+     *
+     *   BGP_ERR_INACTIVE when there is no session.
+     *
+     *   BGP_ERR_NOT_SUPPORTED when TCP MD5 Signature Option is not supported
+     *   (e.g. the underlying TCP stack does not support it)
+     *
+     */
+    i32 setPeerSecret(1:string ipAddress, 2:string rfc2385_sharedSecret),
     i32 deletePeer(1:string ipAddress)
     i32 addVrf(1:layer_type l_type, 2:string rd, 3:list<string> irts, 4:list<string> erts),
     i32 delVrf(1:string rd),

An old server (i.e. using a previous version of qbgp.thrift) will return a TApplicationException with type UNKNOWN_METHOD. See [TBaseProcessor].

Configuration impact

No configuration parameters deprecated.

New optional leaf tcp-md5-signature-password does not impact existing deployments.

The recommended AAA configuration (See Security considerations) may impact existing deployments.

Other Infra considerations

Signature mismatch

On signature mismatch TCP MD5 Signature Option [RFC2385] (page 2) specifies the following behaviour:

RFC 2385 page 2
Upon receiving a signed segment, the receiver must validate it by
calculating its own digest from the same data (using its own key) and
comparing the two digest.  A failing comparison must result in the
segment being dropped and must not produce any response back to the
sender.  Logging the failure is probably advisable.

A BGP will be unable to connect with a neighbor with a wrong password because the TCP SYN,ACK will be dropped. The neighbor state will bounce between “Active” and “Connect” while it retries.

Security considerations

tcp-md5-signature-password is stored in clear in the datastore. This is a limitation of the proposed change.

Because tcp-md5-signature-password is stored in clear the REST access to neighbors list should be restricted. See the following AAA configuration examples:

etc/shiro.ini example
# DISCOURAGED since Carbon
/config/ebgp:bgp/neighbors/** = authBasic, roles[admin]
AAA MDSALDynamicAuthorizationFilter example
{ "aaa:policies":
   {  "aaa:policies": [
      {  "aaa:resource": "/restconf/config/ebgp:bgp/neighbors/**",
         "aaa:permissions": [
         {  "aaa:role": "admin",
            "aaa:actions": [ "get","post","put","patch","delete" ]
         } ]
      } ]

If BgpConfigurator thrift service is not secured then tcp-md5-signature-password goes clear on the wire.

Quagga [QBGP] (up to version 1.0) keeps the password in memory in clear. The password can be retrieved through Quagga’s configuration interface.

Scale and Performance Impact

Negligible scale or performance impacts.

  • datastore: A bounded (<=80) string per configured neighbor.
  • Traffic (thrift BgpConfigurator service): A bounded (<=80) string field per neighbor addition operation.


Three alternatives have been considered in order to avoid storing the plain password in datastore: RPC, post-update, and transparent encryption. They are briefly described below.

The best alternative is transparent encryption, but in Carbon time-frame is not feasible.

The post-update alternative does not actually solve the limitation.

The RPC alternative is feasible in Carbon time-frame but, given that currently BgpConfigurator thrift service is not secured, to add an RPC does not pull its weight.

RPC encryption

A new RPC add-neighbor(address, as-number[, tcp-md5-signature-password]) is in charge of create neighbors elements. The password is salted and encrypted with aaa-encryption-service. Both the salt and the encrypted password are stored in the neighbors element.

Post-update encryption

The neighbors element contains both a plain-password leaf and a encrypted-password-with-salt leaf. The listener BgpConfigurationManager.NeighborsReactor is in charge of encrypt and remove the plain-password leaf when it is present (and the encrypted one is not).

This alternative does not really solve the limitation because during a brief period the password is stored in plain.

Transparent encryption

A plain value is provided in REST write operations but it is automagically encrypted before it reaches MD-SAL. Read operations never decrypts the encrypted values.

This alternative impacts at least aaa, yangtools, and netconf projects. It can not possibly be done in Carbon.


Features to Install



The RESTful API for neighbors creation (/restconf/config/ebgp:bgp/neighbors/{address}) will be enhanced to accept an additional tcp-md5-signature-password attribute:

{ "neighbors": {
   "address": "",
   "remote-as": "2791",
   "tcp-md5-signature-password": "password"


A new option --tcp-md5-password will be added to commands odl:configure-bgp and odl:bgp-nbr.

opendaylight-user@root> odl:configure-bgp -op add-neighbor --ip --as-num 2791 --tcp-md5-password password
opendaylight-user@root> odl:bgp-nbr --ip-address --as-number 2791 --tcp-md5-password password add



Primary assignee:
Jose-Santos Pulido, JoseSantos,
Other contributors:

Work Items

  1. Spec
  2. ebgp.yang
  3. BgpConfigurator thrift service (both idl and client)
  4. BgpConfigurationManager.NeighborsReactor
  5. ConfigureBgpCli



No internal dependencies are added or removed.


To enable TCP MD5 Signature Option [RFC2385] in a BGP the following conditions need to be met:

  • BgpConfigurator thrift service provider (e.g. Zebra Remote Procedure Call [ZRPC]) must support the new function setPeerSecret.
  • BGP’s TCP stack must support TCP MD5 Signature Option (e.g. in linux the kernel option CONFIG_TCP_MD5SIG must be set).


Unit Tests

Currently bgpmanager has no unit tests related to configuration.

Integration Tests

Currently bgpmanager has no integration tests.


Currently there is no CSIT test exercising bgpmanager.

Documentation Impact

Currently there is no documentation related to bgpmanager.