Hello! At the end I could make it work. I followed the steps of the actions regarding ARP. I changed where to perform the commit_action function and moved it to commit_set_nw_action. Now works perfectly. I do not know what behaviour changes perform this change I did, but the thing that matters is that it works now.
Kind regards and thank you for your help, Raúl Suárez 2015-03-19 22:14 GMT+00:00 Jarno Rajahalme <jrajaha...@nicira.com>: > Any custom actions need to be supported by the datapaths, otherwise they > fail flow setup validation. Linux datapath (kernel module) is part of the > linux kernel sources, but if you need to try out something you can test > your feature with the userspace datapath first, then maybe with the > ova-tree linux kernel module in the datapath directory. > > However, if you are adding support for a new packet header field (as > hinted by MY_FIELD), you should not need to implement any new actions, as > you should be able to use the set_field action. > > Jarno > > > On Mar 19, 2015, at 2:38 PM, Raul Suarez Marin < > raul.suarez.ma...@gmail.com> wrote: > > Thanks Jarno for the hints! > > I found this function looking for ", struct dpif_op " term in every file. > > static void dpif_linux_operate(struct dpif *dpif_, struct dpif_op **ops, > size_t n_ops) > > The main lines in that function of my interest are: > dpif_linux_encode_execute(dpif->dp_ifindex, execute, &aux->request); > nl_transact_multiple(NETLINK_GENERIC, txnsp, n_ops); > > As I understand from this function, and following the path for op->type > = DPIF_OP_EXECUTE, a request is sent at > "nl_transact_multiple(NETLINK_GENERIC, txnsp, n_ops);" through > NETLINK_GENERIC protocol (to the kernel?, any hint to where are they > sent?). Inside this function, I can find these important functions: > > lib/netlink-socket.c: > nl_sock_transact_multiple__(struct nl_sock *sock, > struct nl_transaction **transactions, size_t n, > size_t *done) { > /* some lines */ > do { > error = sendmsg(sock->fd, &msg, 0) < 0 ? errno : 0; > } while (error == EINTR); > > /* some lines */ > > error = nl_sock_recv__(sock, buf_txn->reply, false); > > /* some lines */ > > The thing is that when my action is performed, the error value is 0 (BAD, > packet is not sent); and when it is not performed, error = 11 = EAGAIN (OK, > actions are performed and packet is sent). I guess this means that whoever > receives the request, still does not understand the meaning of the custom > action I am creating. > > I will be posting here any updates I have. > > Kind regards, > Raúl Suárez > > > 2015-03-19 20:50 GMT+01:00 Jarno Rajahalme <jrajaha...@nicira.com>: > >> Raúl, >> >> The dip class functions are implemented by the different dip classes. >> Linux and Windows data paths are interfaced by lib/dpif-netlink.c and the >> userspace datapath is implemented in lib/dpif-netlink.c. You’ll find a >> class struct with the local function pointers in those files, just search >> for “operate” in those files. >> >> Hope this helps, >> >> Jarno >> >> > On Mar 19, 2015, at 2:06 AM, Raul Suarez Marin < >> raul.suarez.ma...@gmail.com> wrote: >> > >> > Hello again, >> > >> > At lib/dpif.c in function "dpif_operate" there is a line that is being >> > called. >> > dpif->dpif_class->operate(dpif, ops, chunk); >> > >> > This is possibly the actions are performed, but I have no clue how to >> know >> > what function this line leads to. >> > >> > In lib/dpif-provider.h I can find the definition for these structs, but >> I >> > can only see: >> > >> > /* Executes each of the 'n_ops' operations in 'ops' on 'dpif', in the >> order >> > * in which they are specified, placing each operation's results in the >> > * "output" members documented in comments. >> > * >> > * This function is optional. It is only worthwhile to implement it if >> > * 'dpif' can perform operations in batch faster than individually. */ >> > void (*operate)(struct dpif *dpif, struct dpif_op **ops, size_t n_ops); >> > >> > Kind regards, >> > Raúl Suárez >> > >> > 2015-03-18 21:26 GMT+01:00 Raul Suarez Marin < >> raul.suarez.ma...@gmail.com>: >> > >> >> Hello Ben, >> >> >> >> Thank you for your answer. Let me correct myself when I said I adapated >> >> parts of "handle_upcalls", I realized I just added debugging lines only >> >> (my bad). >> >> I am trying to do the ovs-vswitchd ofproto/trace command but I am >> getting >> >> failed connection attempts because "address family is not supported by >> >> protocol". I will sort it out. >> >> >> >> My thoughts right now are: >> >> 1) I have done in "do_xlate_actions" the part of reading the field I >> want >> >> to apply the action to. (new case OFPACT_MY_FIELD) >> >> 2) I adapted "commit_odp_actions" which is called >> >> by "compose_output_action" which is called by "xlate_output_action" >> which >> >> is called by "do_xlate_actions" (case OFPACT_OUTPUT) and it is located >> in >> >> "lib/ofp-util.c" This function adds the actions to the ofpbuf at >> ctx->xout->odp_actions >> >> with enum ovs_key = OVS_KEY_ATTR_MY_FIELD. I think there is no way this >> >> fails (because it's just appending data). >> >> 3) Added OVS_KEY_ATTR_MY_FIELD where needed. Specially in function >> >> "odp_execute_set_action" at lib/ofp-execute.c, where looks like that >> the >> >> packet is actually modified. There, I do this: >> >> >> >> const struct ovs_key_STRUCTURE_MODEL my_key = nl_attr_get_unspec(a, >> >> sizeof(struct ovs_key_STRUCTURE_MODEL)) >> >> struct MY_STRUCTURE *packet_to_do_action = ofpbuf_l3(packet); >> >> packet_to_do_action ->my_field = my_key ->my_field; >> >> >> >> This should make it. >> >> >> >> BUT, HERE is the problem! >> >> >> >> I placed this code at "odp_execute_set_action" [function in 3)] >> >> >> >> FILE *f; >> >> f = fopen("/home/raul/match_event2.txt", "ab+"); >> >> fprintf(f, "->odp_execute_set_action(%d)\n", type); >> >> fclose(f); >> >> >> >> This is what I use for debugging. It is a very ugly way of doing it >> but it >> >> works for me. But, this line is not printed when debugging, so the code >> >> never arrives at this point (even if my action is not implemented). >> >> However, when my action is not implemented the action execution works, >> but >> >> still the said line is not printed... so maybe it executes that code >> but it >> >> is not able to print, I do not know really. >> >> >> >> I will be posting here updates so anyone trying to do this same thing >> can >> >> have a "clear" idea of what to do. >> >> >> >> Thanks again Ben for your help, hints and guidelines. >> >> >> >> Kind regards, >> >> Raúl Suárez >> >> >> >> >> >> 2015-03-12 16:06 GMT+01:00 Ben Pfaff <b...@nicira.com>: >> >> >> >>> On Thu, Mar 12, 2015 at 09:11:11AM +0100, Raul Suarez Marin wrote: >> >>>> I am trying to develop new actions for openvswitch, I have done all >> my >> >>> work >> >>>> but looks like it does not work. >> >>>> >> >>>> What I have done: >> >>>> -> Enable ovs to read and parse new actions, so they appear on >> ovs-ofctl >> >>>> dump-flows command. >> >>>> -> Adapted required parts of "handle_upcalls" function >> >>>> at ofproto\ofproto-dpif-upcall.c (and inside functions) >> >>>> -> Adapted "do_xlate_actions" function at >> ofproto\ofproto-dpif-xlate.c >> >>>> >> >>>> The problem is: >> >>>> If the new action is not programmed, everything goes as expected. >> >>>> If the new action is programmed, no packet forwarding is done. >> >>>> >> >>>> The last sentence means that I have done all my work, but part of it >> is >> >>>> wrong, or that I am still missing something? >> >>> >> >>> I think you've hit the right parts of the code. Try ofproto/trace >> (see >> >>> ovs-vswitchd(8)) for some hints. >> >>> >> >>> A new action wouldn't normally need any changes in handle_upcalls(). >> >>> >> >> >> >> >> > _______________________________________________ >> > dev mailing list >> > dev@openvswitch.org >> > http://openvswitch.org/mailman/listinfo/dev >> >> > > _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev