point at the snippet of user input that matched it.
For most nontrivial commands the handler function will need to determine which
-of the possible matching inputs was entered. Previously this was done by looking
-at the first few characters of input. This is now considered an anti-pattern and
-should be avoided. Instead, the ``->type`` or ``->text`` fields for this logic.
-The ``->type`` field can be used when the possible inputs differ in type. When
-the possible types are the same, use the ``->text`` field. This field has the
-full text of the corresponding token in the definition string and using it makes
-for much more readable code. An example is helpful.
+of the possible matching inputs was entered. Previously this was done by
+looking at the first few characters of input. This is now considered an
+anti-pattern and should be avoided. Instead, use the ``->type`` or ``->text``
+fields for this logic. The ``->type`` field can be used when the possible
+inputs differ in type. When the possible types are the same, use the ``->text``
+field. This field has the full text of the corresponding token in the
+definition string and using it makes for much more readable code. An example is
+helpful.
Command definition:
command <(1-10)|foo|BAR>
In this example, the user may enter any one of:
-- an integer between 1 and 10
-- "foo"
-- anything at all
+
+* an integer between 1 and 10
+* "foo"
+* anything at all
If the user enters "command f", then:
To add a new CLI node, you should:
-- define a new numerical node constant
-- define a node structure in the relevant daemon
-- call ``install_node()`` in the relevant daemon
-- define and install the new node in vtysh
-- define corresponding node entry commands in daemon and vtysh
-- add a new entry to the ``ctx_keywords`` dictionary in ``tools/frr-reload.py``
+#. define a new numerical node constant
+#. define a node structure in the relevant daemon
+#. call ``install_node()`` in the relevant daemon
+#. define and install the new node in vtysh
+#. define corresponding node entry commands in daemon and vtysh
+#. add a new entry to the ``ctx_keywords`` dictionary in ``tools/frr-reload.py``
Defining the numerical node constant
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The algorithm is as followed:
-```
- cost = MAX_COST;
- Priority_Queue.empty();
- Visited_Node.empty();
- Processed_Path.empty();
- src = new_path(source_address);
- src.cost = 0;
- dst = new_destinatio(destination_address);
- dst.cost = MAX_COST;
- Processed_Path.add(src);
- Processed_Path.add(dst);
- while (Priority_Queue.count != 0) {
- current_path = Priority_Queue.pop();
- current_node = next_path.destination;
- Visited_Node.add(current_node);
- for (current_node.edges: edge) {
- if (prune_edge(current_path, edge)
- continue;
- if (relax(current_path) && cost > current_path.cost) {
- optim_path = current_path;
- cost = current_path.cost;
- }
- }
- }
-
- prune_edge(path, edge) {
- // check that path + edge meet constraints e.g.
- if (current_path.cost + edge.cost > constrained_cost)
- return false;
- else
- return true;
- }
-
- relax_edge(current_path, edge) {
- next_node = edge.destination;
- if (Visited_Node.get(next_node))
- return false;
- next_path = Processed_Path.get(edge.destination);
- if (!next_path) {
- next_path = new path(edge.destination);
- Processed_Path.add(next_path);
- }
- total_cost = current_path.cost + edge.cost;
- if (total_cost < next_path.cost) {
- next_path = current_path;
- next_path.add_edge(edge);
- next_path.cost = total_cost;
- Priority_Queue.add(next_path);
- }
- return (next_path.destination == destination);
- }
-
-```
+.. code-block:: c
+
+ cost = MAX_COST;
+ Priority_Queue.empty();
+ Visited_Node.empty();
+ Processed_Path.empty();
+ src = new_path(source_address);
+ src.cost = 0;
+ dst = new_destinatio(destination_address);
+ dst.cost = MAX_COST;
+ Processed_Path.add(src);
+ Processed_Path.add(dst);
+ while (Priority_Queue.count != 0) {
+ current_path = Priority_Queue.pop();
+ current_node = next_path.destination;
+ Visited_Node.add(current_node);
+ for (current_node.edges: edge) {
+ if (prune_edge(current_path, edge)
+ continue;
+ if (relax(current_path) && cost > current_path.cost) {
+ optim_path = current_path;
+ cost = current_path.cost;
+ }
+ }
+ }
+
+ prune_edge(path, edge) {
+ // check that path + edge meet constraints e.g.
+ if (current_path.cost + edge.cost > constrained_cost)
+ return false;
+ else
+ return true;
+ }
+
+ relax_edge(current_path, edge) {
+ next_node = edge.destination;
+ if (Visited_Node.get(next_node))
+ return false;
+ next_path = Processed_Path.get(edge.destination);
+ if (!next_path) {
+ next_path = new path(edge.destination);
+ Processed_Path.add(next_path);
+ }
+ total_cost = current_path.cost + edge.cost;
+ if (total_cost < next_path.cost) {
+ next_path = current_path;
+ next_path.add_edge(edge);
+ next_path.cost = total_cost;
+ Priority_Queue.add(next_path);
+ }
+ return (next_path.destination == destination);
+ }
+
Definition
----------
.. code-block:: c
- struct cspf *algo;
- struct ls_ted *ted;
- struct in_addr src;
- struct in_addr dst;
- struct constraints csts;
- struct c_path *path;
-
- // Create a new CSPF structure
- algo = cspf_new();
-
- // Initialize constraints
- csts.cost = 100;
- csts.ctype = CSPF_TE_METRIC;
- csts.family = AF_INET;
- csts.type = SR_TE;
- csts.bw = 1000000;
- csts.cos = 3;
-
- // Then, initialise th CSPF with source, destination and constraints
- cspf_init_v4(algo, ted, src, dst, &csts);
-
- // Finally, got the Computed Path;
- path = compute_p2p_path(ted, algo);
-
- if (path.status == SUCCESS)
- zlog_info("Got a valid constraints path");
- else
- zlog_info("Unable to compute constraints path. Got %d status", path->status);
+ struct cspf *algo;
+ struct ls_ted *ted;
+ struct in_addr src;
+ struct in_addr dst;
+ struct constraints csts;
+ struct c_path *path;
+
+ // Create a new CSPF structure
+ algo = cspf_new();
+
+ // Initialize constraints
+ csts.cost = 100;
+ csts.ctype = CSPF_TE_METRIC;
+ csts.family = AF_INET;
+ csts.type = SR_TE;
+ csts.bw = 1000000;
+ csts.cos = 3;
+
+ // Then, initialise th CSPF with source, destination and constraints
+ cspf_init_v4(algo, ted, src, dst, &csts);
+
+ // Finally, got the Computed Path;
+ path = compute_p2p_path(ted, algo);
+
+ if (path.status == SUCCESS)
+ zlog_info("Got a valid constraints path");
+ else
+ zlog_info("Unable to compute constraints path. Got %d status", path->status);
If you would compute another path, you must call `cspf_init()` prior to