)]}'
{
  "log": [
    {
      "commit": "04a3aabf58d95d01c4c8168eeff43cf9d9892eee",
      "tree": "c810fdc3ff48d185bb34ce73e986a2c88da3780f",
      "parents": [
        "0bc874b88cf86fca4b18f3672a441ed142fc499d"
      ],
      "author": {
        "name": "Nicolas Dichtel",
        "email": "nicolas.dichtel@6wind.com",
        "time": "Thu Sep 03 10:47:43 2015 +0200"
      },
      "committer": {
        "name": "Paul Jakma",
        "email": "paul@quagga.net",
        "time": "Thu Sep 24 15:26:45 2015 +0100"
      },
      "message": "vrf: add a runtime check before playing with netns\n\nThis patch adds a runtime check to determine if netns are available. Some\nsystems like OpenWRT have the system call setns() but don\u0027t have the kernel\noption CONFIG_NET_NS enabled.\n\nReported-by: Christian Franke \u003cchris@opensourcerouting.org\u003e\nSigned-off-by: Nicolas Dichtel \u003cnicolas.dichtel@6wind.com\u003e\nTested-by: Christian Franke \u003cchris@opensourcerouting.org\u003e\n"
    },
    {
      "commit": "55cfa2f190620f7c711944637659bc208970324d",
      "tree": "13e8a607e6e552da0f4218b4a8473dbcd738845b",
      "parents": [
        "c99f3481a598e9cadd1de96714f6b5df9ad85c4a"
      ],
      "author": {
        "name": "Feng Lu",
        "email": "lu.feng@6wind.com",
        "time": "Thu Jul 03 18:24:34 2014 +0800"
      },
      "committer": {
        "name": "Nicolas Dichtel",
        "email": "nicolas.dichtel@6wind.com",
        "time": "Wed Jun 03 17:26:27 2015 +0200"
      },
      "message": "lib, vtysh: support multiple VRFs by using linux netns\n\nWe realize VRFs with linux netns by default. The main job is\nto associate a VRF with a netns. Currently this is done by\nthe configuration:\n\n  [no] vrf N netns \u003cnetns-name\u003e\n\nThis command is also available in vtysh and goes to only\nzebra, because presently only zebra supports multiple VRF.\n\nA file descriptor is added to \"struct vrf\". This is for the\nassociated netns file. Once the command \"vrf N netns NAME\"\nis executed, the specified file is opened and the file\ndescriptor is stored in the VRF N. In this way the\nassociation is formed.\n\nIn vrf_socket(), we first switch to the specified VRF by\nusing the stored file descriptor, and then can allocate\na socket which is working in the associated netns.\n\nSigned-off-by: Feng Lu \u003clu.feng@6wind.com\u003e\nReviewed-by: Alain Ritoux \u003calain.ritoux@6wind.com\u003e\nSigned-off-by: Nicolas Dichtel \u003cnicolas.dichtel@6wind.com\u003e\n"
    },
    {
      "commit": "c99f3481a598e9cadd1de96714f6b5df9ad85c4a",
      "tree": "aac6df566f28c13fce5c9f02275f159fab73a24d",
      "parents": [
        "758fb8f99a7bfac3d31c419fd1a5694fc5f33f6a"
      ],
      "author": {
        "name": "Feng Lu",
        "email": "lu.feng@6wind.com",
        "time": "Thu Oct 16 09:52:36 2014 +0800"
      },
      "committer": {
        "name": "Nicolas Dichtel",
        "email": "nicolas.dichtel@6wind.com",
        "time": "Wed Jun 03 10:24:12 2015 +0200"
      },
      "message": "*: add VRF ID in the API message header\n\nThe API messages are used by zebra to exchange the interfaces, addresses,\nroutes and router-id information with its clients. To distinguish which\nVRF the information belongs to, a new field \"VRF ID\" is added in the\nmessage header. And hence the message version is increased to 3.\n\n* The new field \"VRF ID\" in the message header:\n\n    Length    (2 bytes)\n    Marker    (1 byte)\n    Version   (1 byte)\n    VRF ID    (2 bytes, newly added)\n    Command   (2 bytes)\n\n  - Client side:\n\n    - zclient_create_header() adds the VRF ID in the message header.\n    - zclient_read() extracts and validates the VRF ID from the header,\n      and passes the VRF ID to the callback functions registered to\n      the API messages.\n    - All relative functions are appended with a new parameter \"vrf_id\",\n      including all the callback functions.\n    - \"vrf_id\" is also added to \"struct zapi_ipv4\" and \"struct zapi_ipv6\".\n      Clients need to correctly set the VRF ID when using the API\n      functions zapi_ipv4_route() and zapi_ipv6_route().\n    - Till now all messages sent from a client have the default VRF ID\n      \"0\" in the header.\n    - The HELLO message is special, which is used as the heart-beat of\n      a client, and has no relation with VRF. The VRF ID in the HELLO\n      message header will always be 0 and ignored by zebra.\n\n  - Zebra side:\n\n    - zserv_create_header() adds the VRF ID in the message header.\n    - zebra_client_read() extracts and validates the VRF ID from the\n      header, and passes the VRF ID to the functions which process\n      the received messages.\n    - All relative functions are appended with a new parameter \"vrf_id\".\n\n* Suppress the messages in a VRF which a client does not care:\n\n  Some clients may not care about the information in the VRF X, and\n  zebra should not send the messages in the VRF X to those clients.\n\n  Extra flags are used to indicate which VRF is registered by a client,\n  and a new message ZEBRA_VRF_UNREGISTER is introduced to let a client\n  can unregister a VRF when it does not need any information in that\n  VRF.\n\n  A client sends any message other than ZEBRA_VRF_UNREGISTER in a VRF\n  will automatically register to that VRF.\n\n  - lib/vrf:\n\n    A new utility \"VRF bit-map\" is provided to manage the flags for\n    VRFs, one bit per VRF ID.\n\n    - Use vrf_bitmap_init()/vrf_bitmap_free() to initialize/free a\n      bit-map;\n    - Use vrf_bitmap_set()/vrf_bitmap_unset() to set/unset a flag\n      in the given bit-map, corresponding to the given VRF ID;\n    - Use vrf_bitmap_check() to test whether the flag, in the given\n      bit-map and for the given VRF ID, is set.\n\n  - Client side:\n\n    - In \"struct zclient\", the following flags are changed from\n      \"u_char\" to \"vrf_bitmap_t\":\n          redist[ZEBRA_ROUTE_MAX]\n          default_information\n      These flags are extended for each VRF, and controlled by the\n      clients themselves (or with the help of zclient_redistribute()\n      and zclient_redistribute_default()).\n\n  - Zebra side:\n\n    - In \"struct zserv\", the following flags are changed from\n      \"u_char\" to \"vrf_bitmap_t\":\n          redist[ZEBRA_ROUTE_MAX]\n          redist_default\n          ifinfo\n          ridinfo\n\n      These flags are extended for each VRF, as the VRF registration\n      flags. They are maintained on receiving a ZEBRA_XXX_ADD or\n      ZEBRA_XXX_DELETE message.\n\n      When sending an interface/address/route/router-id message in\n      a VRF to a client, if the corresponding VRF registration flag\n      is not set, this message will not be dropped by zebra.\n\n    - A new function zread_vrf_unregister() is introduced to process\n      the new command ZEBRA_VRF_UNREGISTER. All the VRF registration\n      flags are cleared for the requested VRF.\n\n  Those clients, who support only the default VRF, will never receive\n  a message in a non-default VRF, thanks to the filter in zebra.\n\n* New callback for the event of successful connection to zebra:\n\n  - zclient_start() is splitted, keeping only the code of connecting\n    to zebra.\n\n  - Now zclient_init()\u003d\u003ezclient_connect()\u003d\u003ezclient_start() operations\n    are purely dealing with the connection to zbera.\n\n  - Once zebra is successfully connected, at the end of zclient_start(),\n    a new callback is used to inform the client about connection.\n\n  - Till now, in the callback of connect-to-zebra event, all clients\n    send messages to zebra to request the router-id/interface/routes\n    information in the default VRF.\n\n    Of corse in future the client can do anything it wants in this\n    callback. For example, it may send requests for both default VRF\n    and some non-default VRFs.\n\nSigned-off-by: Feng Lu \u003clu.feng@6wind.com\u003e\nReviewed-by: Alain Ritoux \u003calain.ritoux@6wind.com\u003e\nSigned-off-by: Nicolas Dichtel \u003cnicolas.dichtel@6wind.com\u003e\nAcked-by: Donald Sharp \u003csharpd@cumulusnetworks.com\u003e\n"
    },
    {
      "commit": "fb2bfc1ba2416c1561bc9bfb30dfb5adf3e65616",
      "tree": "361484e61445a5e7efc9dfab2d6c47cd4c63846c",
      "parents": [
        "ac19a449261bf69e83827f4bb0c6e5526277b41b"
      ],
      "author": {
        "name": "Feng Lu",
        "email": "lu.feng@6wind.com",
        "time": "Fri May 22 11:40:08 2015 +0200"
      },
      "committer": {
        "name": "David Lamparter",
        "email": "equinox@opensourcerouting.org",
        "time": "Tue Jun 02 07:48:34 2015 +0200"
      },
      "message": "lib/vrf: enable / disable a VRF\n\nA new API vrf_is_enabled() is defined to check whether a VRF is ready\nto use, that is, to allocate resources in that VRF. Currently there\u0027s\nonly one type of resource: socket.\n\nTwo new hooks VRF_ENABLE_HOOK/VRF_DISABLE_HOOK are introduced to tell\nthe user when a VRF gets ready or to be unavailable.\n\nThe VRF_ENABLE_HOOK callback is called in the new function vrf_enable(),\nwhich is used to let the VRF be ready to use. Till now, only the default\nVRF can be enabled, and we need do nothing to enable the default, except\ncalling the hook.\n\nThe VRF_DISABLE_HOOK callback is called in the new function\nvrf_disable(), which is used to let the VRF be unusable. Till now,\nit is called only when the VRF is to be deleted.\n\nA new utility vrf_socket() is defined to provide a socket in a given\nVRF to the user.\n\nTill now before introducing a way of VRF realization, only the default\nVRF is enabled since its birth, and vrf_socket() creates socket for\nonly the default VRF.\n\nThis patch defines the framework of the VRF APIs. The way they serve\nthe users is:\n- vrf_is_enabled() is used to tell the user whether a VRF is usable;\n- users are informed by the VRF_ENABLE_HOOK that a VRF gets usable;\n  they can allocate resources after that;\n- users are informed by the VRF_DISABLE_HOOK that a VRF is to be\n  unavailable, and they must release the resources instantly;\n- vrf_socket() is used to provide a socket in a given VRF.\n\nSigned-off-by: Feng Lu \u003clu.feng@6wind.com\u003e\nReviewed-by: Alain Ritoux \u003calain.ritoux@6wind.com\u003e\nSigned-off-by: Nicolas Dichtel \u003cnicolas.dichtel@6wind.com\u003e\nAcked-by: Vincent JARDIN \u003cvincent.jardin@6wind.com\u003e\nSigned-off-by: David Lamparter \u003cequinox@opensourcerouting.org\u003e\n"
    },
    {
      "commit": "5a5702fac5458d63d7a099c4db7ac387afefd2de",
      "tree": "0547fea145cb10fb9ed6d9493963d374556eb65f",
      "parents": [
        "126215c1238eb42cc92d23aefbe1fac3b204438f"
      ],
      "author": {
        "name": "Feng Lu",
        "email": "lu.feng@6wind.com",
        "time": "Fri May 22 11:39:59 2015 +0200"
      },
      "committer": {
        "name": "David Lamparter",
        "email": "equinox@opensourcerouting.org",
        "time": "Tue Jun 02 06:59:28 2015 +0200"
      },
      "message": "lib: move the interface list into \"struct vrf\"\n\nAn interface belongs to a specific VRF. So move the interface list\ninto the \"struct vrf\".\n\n* vrf.c/vrf.h:\n  - add a new member \"struct list *iflist\" to the the \"struct vrf\";\n  - call if_init() in vrf_new();\n  - call if_terminate() in vrf_delete();\n  - add utilities to access the interface list and VRF ID in the\n    specified VRF.\n\n* if.c/if.h:\n  - the global \"iflist\" now only exists for the default VRF;\n  - the global \"if_master\" is initialized on the definition;\n  - in if_create(), the interface is added into the list in the\n    specified VRF; if the VRF does not exist, create one;\n  - add parameters to if_init()/if_terminate() so that the\n    interface list in the VRF can be initialized/destroyed;\n  - in if_dump_all() scan the interfaces in all the VRFs;\n  - add a command \"show address vrf N\" to show addresses in a\n    specified VRF;\n  - add a command \"show address vrf all\" to show addresses in all\n    VRFs;\n  - new APIs ifxxx_vrf() are added to access an interface in a\n    specified VRF.\n\nThe old interface APIs (the global variable \"iflist\" and the API\nfunctions) are not changed to keep the backward compatibility.\nThe new APIs are used in the daemons which support multiple VRFs\n(till now only zebra).\n\nSigned-off-by: Feng Lu \u003clu.feng@6wind.com\u003e\nReviewed-by: Alain Ritoux \u003calain.ritoux@6wind.com\u003e\nSigned-off-by: Nicolas Dichtel \u003cnicolas.dichtel@6wind.com\u003e\nAcked-by: Vincent JARDIN \u003cvincent.jardin@6wind.com\u003e\nSigned-off-by: David Lamparter \u003cequinox@opensourcerouting.org\u003e\n"
    },
    {
      "commit": "126215c1238eb42cc92d23aefbe1fac3b204438f",
      "tree": "22910b50f39003e297efc6236711581cbf3b2ada",
      "parents": [
        "2fc97f6335dd5d7df2c285b363c6ef56bb98dcf8"
      ],
      "author": {
        "name": "Feng Lu",
        "email": "lu.feng@6wind.com",
        "time": "Fri May 22 11:39:58 2015 +0200"
      },
      "committer": {
        "name": "David Lamparter",
        "email": "equinox@opensourcerouting.org",
        "time": "Tue Jun 02 06:58:12 2015 +0200"
      },
      "message": "*: call if_init()/if_terminate() from vrf_init()/vrf_terminate()\n\nLater, an interface will belong to a specific VRF, and the interface\ninitialization will be a part of the VRF initialization. So now call\nif_init() from vrf_init(), and if_terminate() from vrf_terminate().\n\nDaemons have the according changes:\n- if if_init() was called or \"iflist\" was initialized, now call\n  vrf_init() instead;\n- if if_terminate() was called or \"iflist\" was destroyed, now call\n  vrf_terminate() instead.\n\nSigned-off-by: Feng Lu \u003clu.feng@6wind.com\u003e\nReviewed-by: Alain Ritoux \u003calain.ritoux@6wind.com\u003e\nSigned-off-by: Nicolas Dichtel \u003cnicolas.dichtel@6wind.com\u003e\nAcked-by: Vincent JARDIN \u003cvincent.jardin@6wind.com\u003e\nSigned-off-by: David Lamparter \u003cequinox@opensourcerouting.org\u003e\n"
    },
    {
      "commit": "41f44a23e86a65a5cad7e5e8cafd7e935f153232",
      "tree": "1fcffa568b188ae66e5f18df09f6960522dfe564",
      "parents": [
        "395828eea809e8b2b8c5824d3639cefedd7aa9f0"
      ],
      "author": {
        "name": "Feng Lu",
        "email": "lu.feng@6wind.com",
        "time": "Fri May 22 11:39:56 2015 +0200"
      },
      "committer": {
        "name": "David Lamparter",
        "email": "equinox@opensourcerouting.org",
        "time": "Tue Jun 02 06:58:12 2015 +0200"
      },
      "message": "lib, zebra: move \"struct vrf\" to be a lib module\n\nPreviously \"struct vrf\" is defined locally in zebra. Now it is moved\nto be a lib module.\n\nThis is the first step to support multi-VRF in quagga. The\nimplementation is splitted into small patches for the purpose of\neasy review.\n\n* lib:\n    \"struct vrf\" with basic members is defined in vrf.c. The member\n    \"void *info\" is for user data.\n\n    Some basic functions are defined in vrf.c for adding/deleting/\n    looking up a VRF, scanning the VRF table and initializing the\n    VRF module.\n\n    The type \"vrf_id_t\" is defined specificly for VRF ID.\n\n* zebra:\n    The previous \"struct vrf\" is re-defined as \"struct zebra_vrf\";\n    and previous \"vrf\" variables are renamed to \"zvrf\".\n\n    The previous \"struct vrf\" related functions are removed from\n    zbera_rib.c. New functions are defined to maintain the new\n    \"struct zebra_vrf\".\n\n    The names vrf_xxx are reserved for the functions in VRF module.\n    So:\n    - the previous vrf_table() are renamed to zebra_vrf_table();\n    - the previous vrf_static_table() are renamed to\n      zebra_vrf_static_table().\n\n    The main logic is not changed.\n\n    BTW: Add a statement to zebra_snmp.c telling that the SNMP is\n         running only for the MIBs in the default VRF.\n\nSigned-off-by: Feng Lu \u003clu.feng@6wind.com\u003e\nReviewed-by: Alain Ritoux \u003calain.ritoux@6wind.com\u003e\nSigned-off-by: Nicolas Dichtel \u003cnicolas.dichtel@6wind.com\u003e\nAcked-by: Vincent JARDIN \u003cvincent.jardin@6wind.com\u003e\nSigned-off-by: David Lamparter \u003cequinox@opensourcerouting.org\u003e\n"
    }
  ]
}
