Commits

paul authored 3bf1c917d10
2003-10-29 Paul Jakma <paul@dishone.st>

* lib/routemap.c: (route_map_apply_index) renamed to route_map_apply_match. (route_map_apply_match) Take rule list as argument rather than index. concentrate solely on match logic. (route_map_apply) Properly implement the route map statement logic, according to the table, especially the on-match exit policy.
No tags

lib/routemap.c

Modified
627 627 /* Execute event hook. */
628 628 if (route_map_master.event_hook)
629 629 (*route_map_master.event_hook) (RMAP_EVENT_SET_DELETED,
630 630 index->map->name);
631 631 return 0;
632 632 }
633 633 /* Can't find matched rule. */
634 634 return 1;
635 635 }
636 636
637 -/* Apply route map's each index to the object. */
638 -/*
639 -** The matrix for a route-map looks like this:
640 -** (note, this includes the description for the "NEXT"
641 -** and "GOTO" frobs now
642 -**
643 -** Match | No Match
644 -** |
645 -** permit a | c
646 -** |
647 -** ------------------+---------------
648 -** |
649 -** deny b | d
650 -** |
651 -**
652 -** a) Apply Set statements, accept route
653 -** If NEXT is specified, goto NEXT statement
654 -** If GOTO is specified, goto the first clause where pref > nextpref
655 -** If nothing is specified, do as Cisco and finish
656 -** b) Finish route-map processing, and deny route
657 -** c) & d) Goto Next index
658 -**
659 -** If we get no matches after we've processed all updates, then the route
660 -** is dropped too.
661 -**
662 -** Some notes on the new "NEXT" and "GOTO"
663 -** on-match next - If this clause is matched, then the set statements
664 -** are executed and then we drop through to the next clause
665 -** on-match goto n - If this clause is matched, then the set statments
666 -** are executed and then we goto the nth clause, or the
667 -** first clause greater than this. In order to ensure
668 -** route-maps *always* exit, you cannot jump backwards.
669 -** Sorry ;)
670 -**
671 -** We need to make sure our route-map processing matches the above
637 +/* Apply route map's each index to the object.
638 +
639 + The matrix for a route-map looks like this:
640 + (note, this includes the description for the "NEXT"
641 + and "GOTO" frobs now
642 +
643 + Match | No Match
644 + |
645 + permit action | cont
646 + |
647 + ------------------+---------------
648 + |
649 + deny deny | cont
650 + |
651 +
652 + action) Apply Set statements, accept route
653 + If NEXT is specified, goto NEXT statement
654 + If GOTO is specified, goto the first clause where pref > nextpref
655 + If nothing is specified, do as Cisco and finish
656 + deny) If NEXT is specified, goto NEXT statement
657 + If nothing is specified, finally will be denied by route-map.
658 + cont) Goto Next index
659 +
660 + If we get no matches after we've processed all updates, then the route
661 + is dropped too.
662 +
663 + Some notes on the new "NEXT" and "GOTO"
664 + on-match next - If this clause is matched, then the set statements
665 + are executed and then we drop through to the next clause
666 + on-match goto n - If this clause is matched, then the set statments
667 + are executed and then we goto the nth clause, or the
668 + first clause greater than this. In order to ensure
669 + route-maps *always* exit, you cannot jump backwards.
670 + Sorry ;)
671 +
672 + We need to make sure our route-map processing matches the above
672 673 */
674 +
673 675 route_map_result_t
674 -route_map_apply_index (struct route_map_index *index, struct prefix *prefix,
675 - route_map_object_t type, void *object)
676 +route_map_apply_match (struct route_map_rule_list *match_list,
677 + struct prefix *prefix, route_map_object_t type,
678 + void *object)
676 679 {
677 - int ret;
680 + route_map_result_t ret = RMAP_NOMATCH;
678 681 struct route_map_rule *match;
679 - struct route_map_rule *set;
680 -
681 - /* Check all match rule and if there is no match rule return 0. */
682 - for (match = index->match_list.head; match; match = match->next)
683 - {
684 - /* Try each match statement in turn. If any return something
685 - other than RM_MATCH then we don't need to check anymore and can
686 - return */
687 - ret = (*match->cmd->func_apply)(match->value, prefix, type, object);
688 - if (ret != RMAP_MATCH)
689 - return ret;
690 - }
691 682
692 - /* We get here if all match statements matched From the matrix
693 - above, if this is PERMIT we go on and apply the SET functions. If
694 - we're deny, we return indicating we matched a deny */
695 683
696 - /* Apply set statement to the object. */
697 - if (index->type == RMAP_PERMIT)
698 - {
699 - for (set = index->set_list.head; set; set = set->next)
700 - {
701 - ret = (*set->cmd->func_apply)(set->value, prefix, type, object);
702 - }
703 - return RMAP_MATCH;
704 - }
705 - else
684 + /* Check all match rule and if there is no match rule, go to the
685 + set statement. */
686 + if (!match_list->head)
687 + ret = RMAP_MATCH;
688 + else
706 689 {
707 - return RMAP_DENYMATCH;
690 + for (match = match_list->head; match; match = match->next)
691 + {
692 + /* Try each match statement in turn, If any do not return
693 + RMAP_MATCH, return, otherwise continue on to next match
694 + statement. All match statements must match for end-result
695 + to be a match. */
696 + ret = (*match->cmd->func_apply) (match->value, prefix,
697 + type, object);
698 + if (ret != RMAP_MATCH)
699 + return ret;
700 + }
708 701 }
709 - /* Should not get here! */
710 - return RMAP_MATCH;
702 + return ret;
711 703 }
712 704
713 705 /* Apply route map to the object. */
714 706 route_map_result_t
715 -route_map_apply (struct route_map *map, struct prefix *prefix,
716 - route_map_object_t type, void *object)
707 +route_map_apply (struct route_map *map, struct prefix *prefix,
708 + route_map_object_t type, void *object)
717 709 {
718 710 int ret = 0;
719 711 struct route_map_index *index;
712 + struct route_map_rule *set;
720 713
721 714 if (map == NULL)
722 715 return RMAP_DENYMATCH;
723 716
724 717 for (index = map->head; index; index = index->next)
725 718 {
726 - /* Apply this index. End here if we get a RM_NOMATCH */
727 - ret = route_map_apply_index (index, prefix, type, object);
728 -
729 - if (ret != RMAP_NOMATCH)
730 - {
731 - /* We now have to handle the NEXT and GOTO clauses */
732 - if(index->exitpolicy == RMAP_EXIT)
733 - return ret;
734 - if(index->exitpolicy == RMAP_GOTO)
735 - {
736 - /* Find the next clause to jump to */
737 - struct route_map_index *next;
738 -
739 - next = index->next;
740 - while (next && next->pref < index->nextpref)
741 - {
742 - index = next;
743 - next = next->next;
744 - }
745 - if (next == NULL)
746 - {
747 - /* No clauses match! */
748 - return ret;
749 - }
750 - }
751 - /* Otherwise, we fall through as it was a NEXT */
752 - }
719 + /* Apply this index. */
720 + ret = route_map_apply_match (&index->match_list, prefix, type, object);
721 +
722 + /* Now we apply the matrix from above */
723 + if (ret == RMAP_NOMATCH)
724 + /* 'cont' from matrix - continue to next route-map sequence */
725 + continue;
726 + else if (ret == RMAP_MATCH)
727 + {
728 + if (index->type == RMAP_PERMIT)
729 + /* 'action' */
730 + {
731 + /* permit+match must execute sets */
732 + for (set = index->set_list.head; set; set = set->next)
733 + ret = (*set->cmd->func_apply) (set->value, prefix,
734 + type, object);
735 + switch (index->exitpolicy)
736 + {
737 + case RMAP_EXIT:
738 + return ret;
739 + case RMAP_NEXT:
740 + continue;
741 + case RMAP_GOTO:
742 + {
743 + /* Find the next clause to jump to */
744 + struct route_map_index *next = index->next;
745 +
746 + while (next && next->pref < index->nextpref)
747 + {
748 + index = next;
749 + next = next->next;
750 + }
751 + if (next == NULL)
752 + {
753 + /* No clauses match! */
754 + return ret;
755 + }
756 + }
757 + }
758 + }
759 + else if (index->type == RMAP_DENY)
760 + /* 'deny' */
761 + {
762 + if (index->exitpolicy == RMAP_NEXT)
763 + continue;
764 + else
765 + return RMAP_DENYMATCH;
766 + }
767 + }
753 768 }
754 769 /* Finally route-map does not match at all. */
755 770 return RMAP_DENYMATCH;
756 771 }
757 772
758 773 void
759 774 route_map_add_hook (void (*func) (char *))
760 775 {
761 776 route_map_master.add_hook = func;
762 777 }

Everything looks good. We'll let you know here if there's anything you should know about.

Add shortcut