{"action":"opened","issue":{"url":"https://api.github.com/repos/CPqD/ofsoftswitch13/issues/281","repository_url":"https://api.github.com/repos/CPqD/ofsoftswitch13","labels_url":"https://api.github.com/repos/CPqD/ofsoftswitch13/issues/281/labels{/name}","comments_url":"https://api.github.com/repos/CPqD/ofsoftswitch13/issues/281/comments","events_url":"https://api.github.com/repos/CPqD/ofsoftswitch13/issues/281/events","html_url":"https://github.com/CPqD/ofsoftswitch13/issues/281","id":350955045,"node_id":"MDU6SXNzdWUzNTA5NTUwNDU=","number":281,"title":"CPqD Queue Problem","user":{"login":"balotr","id":26579192,"node_id":"MDQ6VXNlcjI2NTc5MTky","avatar_url":"https://avatars2.githubusercontent.com/u/26579192?v=4","gravatar_id":"","url":"https://api.github.com/users/balotr","html_url":"https://github.com/balotr","followers_url":"https://api.github.com/users/balotr/followers","following_url":"https://api.github.com/users/balotr/following{/other_user}","gists_url":"https://api.github.com/users/balotr/gists{/gist_id}","starred_url":"https://api.github.com/users/balotr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/balotr/subscriptions","organizations_url":"https://api.github.com/users/balotr/orgs","repos_url":"https://api.github.com/users/balotr/repos","events_url":"https://api.github.com/users/balotr/events{/privacy}","received_events_url":"https://api.github.com/users/balotr/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-08-15T20:28:44Z","updated_at":"2018-08-15T20:28:44Z","closed_at":null,"author_association":"NONE","body":"Hi I want to declare queue problem again. From mininet one cannot add queue.\r\n\r\nThese are the guys having same problem:\r\nhttps://github.com/CPqD/ofsoftswitch13/issues/259\r\nhttps://github.com/CPqD/ofsoftswitch13/issues/244\r\nhttps://github.com/CPqD/ofsoftswitch13/issues/224\r\nhttps://github.com/CPqD/ofsoftswitch13/issues/222\r\nhttps://github.com/CPqD/ofsoftswitch13/issues/104\r\nhttps://stackoverflow.com/questions/33677006/adding-queues-to-switch-of-ofsoftswitch13-implementation-doesnt-work\r\n(Last one is piece of junk)\r\n\r\nHere is how I encountered problem:\r\n\r\nI wanted to add queue with dpctl utility. When I issue 'dpctl --help', there exists such line:\r\n`SWITCH queue-mod PORT QUEUE BW         adds/modifies queue`\r\nAfter issuing mininet command `sudo mn --mac --switch user --controller remote -x` my user switch connects to controller. I can understand connection from controllers screen and from command `ofprotocol tcp:127.0.0.1:6634`. At output of ofprotocol command datapath id is written with connected message.\r\nWhen I issue  `dpctl tcp:localhost:6634 queue-mod 1 1 80` message, on the screen I get following message:\r\n```\r\nSENDING (xid=0xF0FF00F0):\r\nexpmodqueue{port=\"1\", queue={q=\"1\", props=[minrate{min rate=\"80\"}]}}\r\n\r\n\r\nRECEIVED (xid=0xF0FF00F0):\r\nerror{type=\"QUEUE_OP_FAILED\", code=\"EPERM\", dlen=\"56\"}\r\n```\r\nTo understand if I am doing sth wrong I changed port number and issued command `sudo dpctl unix:/tmp/s1 queue-mod 3 1 100` Here is the output:\r\n```\r\nSENDING (xid=0xF0FF00F0):\r\nexpmodqueue{port=\"3\", queue={q=\"1\", props=[minrate{min rate=\"100\"}]}}\r\n\r\n\r\nRECEIVED (xid=0xF0FF00F0):\r\nerror{type=\"QUEUE_OP_FAILED\", code=\"BAD_PORT\", dlen=\"56\"}\r\n```\r\nI also tried no slicing option but that broke my connection with controller.\r\n\r\nHere is what I did so far to solve problem:\r\n\r\nIn source code of CPqD there exists 2 location where we get type=\"QUEUE_OP_FAILED\", code=\"EPERM\" error. It is in 'udatapath/dp_ports.c' file in dp_ports_handle_queue_modify() function (Starting Line 1017). Here is the code:\r\n```\r\ndp_ports_handle_queue_modify(struct datapath *dp, struct ofl_exp_openflow_msg_queue *msg,\r\n        const struct sender *sender UNUSED) {\r\n    // NOTE: assumes the packet queue has exactly one property, for min rate\r\n    struct sw_port *p;\r\n    struct sw_queue *q;\r\n\r\n    int error = 0;\r\n\r\n    p = dp_ports_lookup(dp, msg->port_id);\r\n    if (PORT_IN_USE(p)) {\r\n        q = dp_ports_lookup_queue(p, msg->queue->queue_id);\r\n        if (q != NULL) {\r\n            /* queue exists - modify it */\r\n            error = netdev_change_class(p->netdev,q->class_id,\r\n                                 ((struct ofl_queue_prop_min_rate *)msg->queue->properties[0])->rate);\r\n             if (error) {\r\n                 VLOG_ERR(LOG_MODULE, \"Failed to update queue %d\", msg->queue->queue_id);\r\n                 return ofl_error(OFPET_QUEUE_OP_FAILED, OFPQOFC_EPERM);\r\n             }\r\n             else {\r\n                 ((struct ofl_queue_prop_min_rate *)q->props->properties[0])->rate =\r\n                         ((struct ofl_queue_prop_min_rate *)msg->queue->properties[0])->rate;\r\n             }\r\n\r\n        } else {\r\n            /* create new queue */\r\n            error = port_add_queue(p, msg->queue->queue_id,\r\n                                       (struct ofl_queue_prop_min_rate *)msg->queue->properties[0]);\r\n            if (error == EXFULL) {\r\n                return ofl_error(OFPET_QUEUE_OP_FAILED, OFPQOFC_EPERM);\r\n            }\r\n\r\n            q = dp_ports_lookup_queue(p, msg->queue->queue_id);\r\n                error = netdev_setup_class(p->netdev,q->class_id,\r\n                                ((struct ofl_queue_prop_min_rate *)msg->queue->properties[0])->rate);\r\n                if (error) {\r\n                    VLOG_ERR(LOG_MODULE, \"Failed to configure queue %d\", msg->queue->queue_id);\r\n                    return ofl_error(OFPET_QUEUE_OP_FAILED, OFPQOFC_BAD_QUEUE);\r\n                }\r\n        }\r\n\r\n    } else {\r\n        VLOG_ERR(LOG_MODULE, \"Failed to create/modify queue - port %d doesn't exist\", msg->port_id);\r\n        return ofl_error(OFPET_QUEUE_OP_FAILED, OFPQOFC_BAD_PORT);\r\n    }\r\n```\r\nSince we are creating new queue I focused create new queue part and followed the code. It comes to following function:\r\n```\r\nport_add_queue(struct sw_port *p, uint32_t queue_id,\r\n               struct ofl_queue_prop_min_rate * mr)\r\n{\r\n    if (queue_id >= p->max_queues) {\r\n        return EXFULL;\r\n    }\r\n\r\n    if (p->queues[queue_id].port != NULL) {\r\n        return EXFULL;\r\n    }\r\n\r\n    return new_queue(p, &(p->queues[queue_id]), queue_id, queue_id, mr);\r\n}\r\n```\r\nIn this function, when I command(/**/) first if I get dpctl: Error during transaction. But when I command second if statement I get exactly the same error with the one when I issue dpctl command. BINGO! Therefore, problem is at first if statement. Since max_queue parameter is below 1 in that port we cannot add queue. I searched ports max_queues parameter. It is uint16_t type and initialized with following statement in new_port function:\r\n\r\n`max_queues = MIN(max_queues, NETDEV_MAX_QUEUES);`\r\n\r\nNETDEV_MAX_QUEUES value is 8 and #defined with preprocessor command)\r\n\r\nnew_port is called in 2 functions in code:\r\n```\r\ndp_ports_add(struct datapath *dp, const char *netdev)\r\n{\r\n    uint32_t port_no;\r\n    for (port_no = 1; port_no < DP_MAX_PORTS; port_no++) {\r\n        struct sw_port *port = &dp->ports[port_no];\r\n        if (port->netdev == NULL) {\r\n            return new_port(dp, port, port_no, netdev, NULL, dp->max_queues);\r\n        }\r\n    }\r\n    return EXFULL;\r\n}\r\n#endif /* OF_HW_PLAT */\r\n\r\nint\r\ndp_ports_add_local(struct datapath *dp, const char *netdev)\r\n{\r\n    if (!dp->local_port) {\r\n        uint8_t ea[ETH_ADDR_LEN];\r\n        struct sw_port *port;\r\n        int error;\r\n\r\n        port = xcalloc(1, sizeof *port);\r\n        eth_addr_from_uint64(dp->id, ea);\r\n        error = new_port(dp, port, OFPP_LOCAL, netdev, ea, 0);\r\n        if (!error) {\r\n            dp->local_port = port;\r\n        } else {\r\n            free(port);\r\n        }\r\n        return error;\r\n    } else {\r\n        return EXFULL;\r\n    }\r\n}\r\n```\r\n\r\nWhen I change new_port(dp, port, OFPP_LOCAL, netdev, ea, 0); or return new_port(dp, port, port_no, netdev, NULL, dp->max_queues); statements I lose connection with controller. Also I lose connection when I make statement max_queues = MIN(max_queues, NETDEV_MAX_QUEUES); to max_queues= 5;\r\n\r\nOf course I run following commands after every change in source code:\r\n```\r\n$ ./boot.sh\r\n$ ./configure\r\n$ make\r\n$ sudo make install \r\n```\r\nIs there a documantation or UML diagrams that explains code further? I would be greatful if I can help you and if you help me :) Sorry for long and boring explanation"}}
{"actor":{"display_login":"balotr"}}