Modifying a config in Opendaylight

735 views Asked by At

I am needing to modify my Openflow configurations in my Opendaylight (0.11.x sodium) system. I follow the documentation which has helped guide is in

  • creating new configs
  • deleting configs
  • replacing configs
  • but I am not seeing an example or explanation on how to modify (or merge) a configuration.

The top paragraph references modifying a config but doesn't actually show an example. And just to be clear, by modification I mean a merge operation. I.e., in terms of the netconf edit-config RFC-6241, I am wanting to modify only some of the leafs of a config, but keep older leafs.

Unfortunately, the options I see given in the openflow documentation is only creating, deleting, and replacing. We need to figure out how to do a merge.

In doing some research, it appears there is functionality with REST PATCH commands, however I am unable to get Opendaylight to work with it. Here is what I am trying:

PATCH //127.0.0.1:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:244354675513412/table/0/flow/105 HTTP/1.1
Content-Type: application/yang.patch+xml
Accept: application/yang.patch+json
Authorization: Basic YWRtaW46YWRtaW4=
User-Agent: PostmanRuntime/7.26.8
Postman-Token: 875a3c91-f6b1-4d21-8f2d-615b3c4b5cdd
Host: 127.0.0.1:8181
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Length: 1233
Cookie: JSESSIONID=node0dqx2exo4lrydz1adjhvc9lum374.node0

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<flow xmlns='urn:opendaylight:flow:inventory' xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0">
    <strict>false</strict>
    <id>105</id>
    <priority>9</priority>
    <table_id>0</table_id>
    <hard-timeout>0</hard-timeout>
    <idle-timeout>0</idle-timeout>
    <flow-name>10dot0SubnetToPort1_from_4</flow-name>
    <match>
       <ethernet-match>
           <ethernet-type>
               <type>2048</type>
           </ethernet-type>
           <ethernet-destination>
               <address>FF:FF:29:01:19:61</address>
           </ethernet-destination>
           <ethernet-source>
               <address>00:00:00:11:23:AE</address>
           </ethernet-source>
       </ethernet-match>
    </match>
    <instructions>
        <instruction>
            <order>1</order>
            <apply-actions>
                <action>
                    <order>0</order>
                    <output-action>
                        <output-node-connector>6</output-node-connector>
                        <max-length>66</max-length>
                    </output-action>
                </action>
            </apply-actions>
        </instruction>
    </instructions>
</flow>

But the response I get back is: 406 Not Acceptable and nothing else... No <error... rpc-response or anything. I also am studying the log files in DEBUG and TRACE mode and can't pick up any hint as to what is going wrong.

I also tried pasting in nc:operation='merge' to each element like this...

...
<output-action nc:operation='merge'>
   <output-node-connector nc:operation='merge'>6</output-node-connector>
   <max-length nc:operation='merge'>66</max-length>
</output-action>
...

But this also results in the same 406 Not Acceptable response.

Goal: how does one properly merge/modify a config in OpenDaylight/Openflow

4

There are 4 answers

3
Arpit J On

Try to install 'odl-restconf-nb-RFC8040' endpoint on your karaf shell. ODL provides two end-point for restconf communication. Although less documents on RFC-8040, yang-patch gives no error through that. (YANG-PATCH allows "create, delete, insert, merge, move, replace, remove" operations. Creating, modifying and deleting configs can be done by changing operation in this payload. https://docs.opendaylight.org/projects/netconf/en/latest/user-guide.html#reconfiguring-an-existing-connector )

RFC-8040 defines YANG-PATCH according to this RFC : https://datatracker.ietf.org/doc/html/draft-ietf-netconf-yang-patch-14#section-2

Your header looks good.

Your API will begin like : PATCH //127.0.0.1:8181/rests/data/.../...

0
Arpit J On

You're correct about 'target' field and its function. However, target field should only contain the name of resource/prefix you're trying to modify.

I'd suggest you to change your flow and target resources accordingly. What I mean by that is you need to make sure the flow and target resources are leading to same resource you're trying to configure.

It should be something like :

PATCH localhost:8181/rests/data/opendaylight-inventory:nodes/node=openflow%3A{{OFID}}/table=0/flow=259/instructions/instruction=0/flow-node-inventory:apply-actions/order=4

and keep Target resource as = /flow-node-inventory:action[flow-node-inventory:order='4']

Try GET on the flow to confirm you're receiving only the resource you're trying to modify/delete.

0
W K On

I have tried to execute yang-patch using the RFC 8040 endpoint and I'm still having some issues--it appears I cannot delete a target with a value other than "/". This is to modify flows in the openflow plugin.

Querying a particular flow here is what I get:

GET localhost:8181/rests/data/opendaylight-inventory:nodes/node=openflow%3A{{OFID}}/table=0/flow=259/instructions/instruction=0

Response:

{
    "flow-node-inventory:instruction": [
        {
            "order": 0,
            "apply-actions": {
                "action": [
                    {
                        "order": 4,
                        "output-action": {
                            "output-node-connector": "2",
                            "max-length": 60
                        }
                    },
                    {
                        "order": 0,
                        "set-field": {
                            "ipv4-source": "10.0.0.254/32"
                        },
                        "set-nw-src-action": {
                            "ipv4-address": "10.0.0.254/32"
                        }
                    },
                    {
                        "order": 1,
                        "set-field": {
                            "ipv4-destination": "10.0.0.21/32"
                        },
                        "set-nw-dst-action": {
                            "ipv4-address": "10.0.0.21/32"
                        }
                    },
                    {
                        "order": 2,
                        "output-action": {
                            "output-node-connector": "2",
                            "max-length": 60
                        }
                    },
                    {
                        "order": 3,
                        "set-field": {
                            "ipv4-destination": "10.0.0.29/32"
                        },
                        "set-nw-dst-action": {
                            "ipv4-address": "10.0.0.29/32"
                        }
                    }
                ]
            }
        }
    ]
}

This is expected--I've installed a flow with specific actions and they're listed appropriately.

Now, let's say I want to delete the action with order=4 above. I would think I would create my request in the following way:

PATCH localhost:8181/rests/data/opendaylight-inventory:nodes/node=openflow%3A{{OFID}}/table=0/flow=259/instructions/instruction=0

Content-type and accept-types are set according to the yang.patch requirements.

Body:

{
  "ietf-restconf:yang-patch" : {
    "patch-id" : "0",
    "edit" : [
        {
        "edit-id" : "edit1",
        "operation" : "delete",
        "target" : "/flow-node-inventory:apply-actions/flow-node-inventory:action[flow-node-inventory:order='4']"
        }
    ]
  }
}

Response:

{
    "ietf-yang-patch:yang-patch-status": {
        "patch-id": "0",
        "edit-status": {
            "edit": [
                {
                    "edit-id": "edit1",
                    "errors": {
                        "error": [
                            {
                                "error-type": "protocol",
                                "error-tag": "data-missing",
                                "error-path": "/(urn:opendaylight:inventory?revision=2013-08-19)nodes/node/node[{(urn:opendaylight:inventory?revision=2013-08-19)id=openflow:152169965450049}]/AugmentationIdentifier{childNames=[(urn:opendaylight:flow:inventory?revision=2013-08-19)description, (urn:opendaylight:flow:inventory?revision=2013-08-19)supported-actions, (urn:opendaylight:flow:inventory?revision=2013-08-19)hardware, (urn:opendaylight:flow:inventory?revision=2013-08-19)switch-features, (urn:opendaylight:flow:inventory?revision=2013-08-19)stale-meter, (urn:opendaylight:flow:inventory?revision=2013-08-19)supported-instructions, (urn:opendaylight:flow:inventory?revision=2013-08-19)meter, (urn:opendaylight:flow:inventory?revision=2013-08-19)serial-number, (urn:opendaylight:flow:inventory?revision=2013-08-19)stale-group, (urn:opendaylight:flow:inventory?revision=2013-08-19)supported-match-types, (urn:opendaylight:flow:inventory?revision=2013-08-19)port-number, (urn:opendaylight:flow:inventory?revision=2013-08-19)table, (urn:opendaylight:flow:inventory?revision=2013-08-19)group, (urn:opendaylight:flow:inventory?revision=2013-08-19)manufacturer, (urn:opendaylight:flow:inventory?revision=2013-08-19)table-features, (urn:opendaylight:flow:inventory?revision=2013-08-19)software, (urn:opendaylight:flow:inventory?revision=2013-08-19)ip-address]}/(urn:opendaylight:flow:inventory?revision=2013-08-19)table/table[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=0}]/flow/flow[{(urn:opendaylight:flow:inventory?revision=2013-08-19)id=259}]/instructions/instruction/instruction[{(urn:opendaylight:flow:inventory?revision=2013-08-19)order=0}]/instruction/apply-actions/action/action[{(urn:opendaylight:flow:inventory?revision=2013-08-19)order=4}]",
                                "error-message": "Data does not exist"
                            }
                        ]
                    }
                }
            ]
        }
    }
}

Now, I know the data exists, but it seems that I cannot request a delete for the particular element I've specified in the target. Indeed, the only way I can delete a particular element is to use "target" : "/", which will delete the child elements according to the last hierarchical element in the URL.

Not sure what I'm doing wrong here--I would have thought I could specify a target and get a delete to execute accordingly, but I'm not sure what else I need to do.

0
Arpit J On

This looks to be an issue of global-level config/node-level config in netconf edit operation. ODL sends out netconf RPCs to mounted netconf devices. I'm certain of later version (11.2 and on) are supporting yang-patch at node-level config. Not sure which version you're using ??

Also this could be an issue of netconf device you're trying to configure, if node-level config is not supported and enabled, ODL could receive error from netconf response.

Either way, checking yang-tool logs on ODL can make this clear for you. you can enable logs on karaf for yang-tools and can set-up detailed logs. That could explain this more.