class Peak::Routing::Rules

Attributes

destination_port[R]
frame[R]
next_target[R]

Public Class Methods

new(frame, config, frame_port, next_target=nil) click to toggle source
# File lib/peak/routing/route.rb, line 5
def initialize(frame, config, frame_port, next_target=nil)
    @frame = frame
    @next_target = next_target
    @config = config
    @frame_port = frame_port
    @destination_port = frame_port

    @port_info = {}
    config.each do |section_name, section_content|
        if section_name.start_with?('TNC ')
            tnc_name = section_name.strip.split(' ')[1].strip
            if tnc_name != 'IGATE'
                port_count = section_content['port_count']

                (1..port_count).each do |port|
                    port_name = tnc_name + '-' + port.to_s
                    port_section_name = 'PORT ' + port_name
                    port_section = config[port_section_name]
                    port_identifier = port_section['identifier']
                    port_net = port_section['net']
                    tnc_port = port_section['tnc_port']

                    old_paradigm = port_section['old_paradigm']
                    unless old_paradigm
                        old_paradigm = []
                    end

                    new_paradigm_all = port_section['new_paradigm']
                    new_paradigm = []
                    if new_paradigm_all and new_paradigm_all.length > 0
                        new_paradigm_all.each do |new_paradigm_one|
                            new_paradigm << {:target => new_paradigm_one['target'], :max_hops => new_paradigm_one['max_hops']}
                        end
                    end

                    preemptive = port_section['preemptive']
    
                    @port_info[port_name] = {
                        :port_identifier => port_identifier,
                        :port_net => port_net,
                        :tnc_port => tnc_port,
                        :old_paradigm => old_paradigm,
                        :new_paradigm => new_paradigm,
                        :preemptive => preemptive
                    }
                end
            end
        end
    end
end

Private Class Methods

args_parser(*args) click to toggle source
# File lib/peak/routing/route.rb, line 57
def self.args_parser(*args)
    if !args or !args.length or args.length <= 0
        condition = args[0]
        true_target = :pass
        false_target = :pass
    elsif !!args[0] == args[0] # if the first argument is a boolean
        condition = args[0]
        true_target = args.length >= 2 ? args[1] : :pass
        false_target = args.length >= 3 ? args[2] : :pass
    else
        condition = true
        true_target = args.length >= 1 ? args[0] : :pass
        false_target = args.length >= 2 ? args[1] : :pass
    end

    next_target = condition ? true_target : false_target

    {
        :condition => condition,
        :true_target => true_target,
        :false_target => false_target,
        :next_target => next_target
    }
end
array_upcase(things) click to toggle source
# File lib/peak/routing/route.rb, line 130
def self.array_upcase(things)
    things.map {|s|
        if !s.is_a? Regexp
            s.upcase
        else
            s
        end
    }
end
consume_new_paradigm(hop) click to toggle source
# File lib/peak/routing/route.rb, line 205
def self.consume_new_paradigm(hop)
    hop_split = hop.split('-')
    target = hop_split[0]
    hop_count = hop_split[1].to_i
    hop_count -= 1
    if hop_count > 0
        hop.replace( target + '-' + hop_count.to_s )
    else
        hop.replace(target + '*')
    end
end
is_hop_identifier_me(hop, identifiers) click to toggle source
# File lib/peak/routing/route.rb, line 196
def self.is_hop_identifier_me(hop, identifiers)
    if identifiers.include? hop.upcase
        true
    else
        false
    end
end
is_hop_new_paradigm?(hop, new_paradigm_all) click to toggle source
# File lib/peak/routing/route.rb, line 163
def self.is_hop_new_paradigm?(hop, new_paradigm_all)
    if new_paradigm_all.length <= 0
        return false
    end

    hop = hop.upcase
    unless hop =~ /[A-Z]*-\d{1,2}/
        return false
    end
    hop_split = hop.split('-')
    if !hop_split or hop_split.length != 2
        return false
    end
    hop_target = hop_split[0]
    hop_hops = hop_split[1].to_i
    if hop_hops <= 0
        return false
    end

    new_paradigm_all.each do |new_paradigm|
        if new_paradigm[:target].is_a? Regexp
            if hop_target =~ new_paradigm[:target]
                return true
            end
        elsif hop_target == new_paradigm[:target].upcase
            return true
        end
    end

    false
end
is_hop_old_paradigm?(hop, old_paradigm) click to toggle source
# File lib/peak/routing/route.rb, line 141
def self.is_hop_old_paradigm?(hop, old_paradigm)
    if old_paradigm.length <= 0
        return false
    end

    old_paradigm = Rules.array_upcase(old_paradigm)
    hop = hop.upcase

    old_paradigm.each do |target|
        if target.is_a? Regexp
            if hop =~ target
                return true
            end
        elsif hop == target
            return true
        end
    end

    false
end

Protected Instance Methods

destination_me?() click to toggle source
# File lib/peak/routing/route.rb, line 313
def destination_me?
    identifiers = @port_info.values.map { |info| info[:port_identifier].upcase }
    if identifiers.include? @frame[:destination].upcase
        true
    else
        false
    end
end
filter(*args) click to toggle source
# File lib/peak/routing/route.rb, line 218
def filter(*args)
    args = Rules.args_parser(*args)
    do_next_target(args[:next_target])
end
future_hop_identifier_me?() click to toggle source
# File lib/peak/routing/route.rb, line 343
def future_hop_identifier_me?
    unless has_next_hop?
        return false
    end

    identifiers = @port_info.values.map { |info| info[:port_identifier].upcase }
    if (identifiers & select_future_hops(Rules.array_upcase(@frame[:path]))).empty?
        false
    else
        true
    end
end
future_hop_me?() click to toggle source
# File lib/peak/routing/route.rb, line 594
def future_hop_me?
    if future_hop_net_me? or future_hop_identifier_me? or future_hop_paradigm?
        true
    else
        false
    end
end
future_hop_net_band_me?() click to toggle source
# File lib/peak/routing/route.rb, line 379
def future_hop_net_band_me?
    unless has_next_hop?
        return false
    end

    net_bands = net_freg_to_band_hops(@port_info.values.map {|info| info[:port_net].upcase })
    next_bands = Rules.array_upcase(select_net_band_hops(@frame[:path]))

    if next_bands.length <= 0 or net_bands.length <= 0
        return false
    end

    if (net_bands & next_bands).empty?
        true
    else
        false
    end
end
future_hop_net_freq_me?() click to toggle source
# File lib/peak/routing/route.rb, line 421
def future_hop_net_freq_me?
    unless has_next_hop?
        return false
    end

    net_freqs = select_net_freq_hops(@port_info.values.map {|info| info[:port_net].upcase })
    next_freqs = select_net_freq_hops(select_future_hops(Rules.array_upcase(@frame[:path])))

    if next_freqs.length <= 0 or net_freqs.length <= 0
        return false
    end

    if (net_freqs & next_freqs).empty?
        true
    else
        false
    end
end
future_hop_net_me?() click to toggle source
# File lib/peak/routing/route.rb, line 558
def future_hop_net_me?
    if future_hop_net_band_me? or future_hop_net_freq_me?
        true
    else
        false
    end
end
future_hop_new_paradigm?() click to toggle source
# File lib/peak/routing/route.rb, line 510
def future_hop_new_paradigm?
    unless has_next_hop?
        return false
    end

    port_name = @frame_port
    port_info = @port_info[port_name]

    if !port_info.key? :new_paradigm or port_info[:new_paradigm].length <= 0
        return false
    end

    new_paradigm_all = port_info[:new_paradigm]
    future_hops = select_future_hops(@frame[:path]).map { |s| s.upcase }
    

    new_paradigm_all.each do |new_paradigm|
        if new_paradigm[:target].is_a? Regexp
            future_hops.each do |hop|
                if hop.include? '-'
                    hop_split = hop.split('-')
                    if hop_split and hop_split.length == 2
                        hop_target = hop_split[0]
                        hop_hops = hop_split[1].to_i
                        if hop_hops > 0 and hop_target =~ new_paradigm[:target]
                            return true
                        end
                    end
                end
            end
        elsif future_hops.include? new_paradigm[:target].upcase
            return true
        end
    end

    false
end
future_hop_old_paradigm?() click to toggle source
# File lib/peak/routing/route.rb, line 460
def future_hop_old_paradigm?
    unless has_next_hop?
        return false
    end

    port_name = @frame_port
    port_info = @port_info[port_name]

    if !port_info.key? :old_paradigm or port_info[:old_paradigm].length <= 0
        return false
    end

    old_paradigm = Rules.array_upcase(port_info[:old_paradigm])
    future_hops = select_future_hops(@frame[:path]).map { |s| s.upcase }

    old_paradigm.each do |target|
        if target.is_a? Regexp
            future_hops.each do |hop|
                if hop =~ target
                    return true
                end
            end
        elsif future_hops.include? target
            return true
        end
    end

    false
end
future_hop_paradigm?() click to toggle source
# File lib/peak/routing/route.rb, line 576
def future_hop_paradigm?
    if future_hop_new_paradigm? or future_hop_old_paradigm?
        true
    else
        false
    end
end
has_next_hop?() click to toggle source
# File lib/peak/routing/route.rb, line 323
def has_next_hop?
    @frame[:path].each do |hop|
        unless hop.end_with? '*'
            return true
        end
    end
    return false
end
mine?() click to toggle source
# File lib/peak/routing/route.rb, line 603
def mine?
    if future_hop_me? or destination_me?
        true
    else
        false
    end
end
next_hop_identifier_me?() click to toggle source
# File lib/peak/routing/route.rb, line 333
def next_hop_identifier_me?
    unless has_next_hop?
        return false
    end

    identifiers = @port_info.values.map { |info| info[:port_identifier].upcase }
    Rules.is_hop_identifier_me(select_next_hop(@frame[:path]), identifiers)
end
next_hop_me?() click to toggle source
# File lib/peak/routing/route.rb, line 585
def next_hop_me?
    if next_hop_net_me? or next_hop_identifier_me? or next_hop_paradigm?
        true
    else
        false
    end
end
next_hop_net_band_me?() click to toggle source
# File lib/peak/routing/route.rb, line 357
def next_hop_net_band_me?
    unless has_next_hop?
        return false
    end

    net_bands = net_freg_to_band_hops(@port_info.values.map {|info| info[:port_net].upcase })
    next_bands = select_net_band_hops([select_next_hop(@frame[:path]).upcase])

    if next_bands.length <= 0 or net_bands.length <= 0
        return false
    end

    next_band = next_bands[0]

    if net_bands.include? next_band
        false
    else
        true
    end
end
next_hop_net_freq_me?() click to toggle source
# File lib/peak/routing/route.rb, line 399
def next_hop_net_freq_me?
    unless has_next_hop?
        return false
    end

    net_freqs = select_net_freq_hops(@port_info.values.map {|info| info[:port_net].upcase })
    next_freqs= select_net_freq_hops([select_next_hop(@frame[:path]).upcase])

    if next_freqs.length <= 0 or net_freqs.length <= 0
        return false
    end

    next_band = next_bands[0]

    if net_bands.include? next_band
        false
    else
        true
    end
end
next_hop_net_me?() click to toggle source
# File lib/peak/routing/route.rb, line 549
def next_hop_net_me?
    if next_hop_net_band_me? or next_hop_net_freq_me?
        true
    else
        false
    end
end
next_hop_new_paradigm?() click to toggle source
# File lib/peak/routing/route.rb, line 491
def next_hop_new_paradigm?
    unless has_next_hop?
        return false
    end

    port_name = @frame_port
    port_info = @port_info[port_name]

    if !port_info.key? :new_paradigm or port_info[:new_paradigm].length <= 0
        return false
    end

    new_paradigm_all = port_info[:new_paradigm]
    next_hop = select_next_hop(@frame[:path]).upcase

    Rules.is_hop_new_paradigm?(next_hop, new_paradigm_all)
end
next_hop_old_paradigm?() click to toggle source
# File lib/peak/routing/route.rb, line 441
def next_hop_old_paradigm?
    unless has_next_hop?
        return false
    end

    port_name = @frame_port
    port_info = @port_info[port_name]

    if !port_info.key? :old_paradigm or port_info[:old_paradigm].length <= 0
        return false
    end

    old_paradigm = Rules.array_upcase(port_info[:old_paradigm])
    next_hop = select_next_hop(@frame[:path]).upcase

    Rules.is_hop_old_paradigm?(next_hop, old_paradigm)
end
next_hop_paradigm?() click to toggle source
# File lib/peak/routing/route.rb, line 567
def next_hop_paradigm?
    if next_hop_new_paradigm? or next_hop_old_paradigm?
        true
    else
        false
    end
end
route(*args, preemptive: nil) click to toggle source
# File lib/peak/routing/route.rb, line 224
def route(*args, preemptive: nil)
    args = Rules.args_parser(*args)

    if has_next_hop? and args[:condition]
        detected = false

        port_name = @frame_port
        port_info = @port_info[port_name]

        if preemptive == nil
            preemptive = port_info[:preemptive]
            if preemptive == nil
                preemptive = true
            end
        end

        old_paradigm = nil
        if port_info.key? :old_paradigm and port_info[:old_paradigm].length > 0
            old_paradigm = Rules.array_upcase(port_info[:old_paradigm])
        end


        new_paradigm = nil
        if port_info.key? :new_paradigm and port_info[:new_paradigm].length > 0
            new_paradigm = port_info[:new_paradigm]
        end


        target = nil
        next_hop = select_next_hop(@frame[:path])
        if all_my_names.include? next_hop.upcase or Rules.is_hop_old_paradigm?(next_hop, old_paradigm)
            target = next_hop.dup
            next_hop << '*'
        elsif Rules.is_hop_new_paradigm?(next_hop, new_paradigm)
            target = next_hop.dup
            Rules.consume_new_paradigm(next_hop)
        end

        if preemptive
            future_hops = select_future_hops(@frame[:path])
            identifiers = @port_info.values.map { |info| info[:port_identifier].upcase }
            future_hops.reverse.each do |hop|
                if detected
                    hop << '*'
                elsif identifiers.include? hop.upcase
                    target = hop.dup
                    hop << '*'
                    detected = true
                end
            end
        end

        if target
            @port_info.each do |name, info|
                identifier = info[:port_identifier].upcase
                net_freq = info[:port_net]
                net_band = net_freq.dup.gsub(/M\d{0,3}$/i, 'M')

                if target == identifier or target == net_freq or target == net_band
                    @destination_port = @frame_port
                end
            end
        end
    end

    do_next_target(args[:next_target])
end
seen?() click to toggle source
# File lib/peak/routing/route.rb, line 293
def seen?
    identifiers = @port_info.values.map { |info| info[:port_identifier].upcase }
    if identifiers.include? @frame[:source].upcase
        return true
    end
    
    @frame[:path].each do |hop|
        unless hop.end_with? '*'
            return false
        end
        
        if identifiers.include? hop.upcase.chomp('*')
            return true
        end
    end
    
    false
end

Private Instance Methods

all_my_names() click to toggle source
# File lib/peak/routing/route.rb, line 122
def all_my_names
    names = @port_info.values.map { |info| info[:port_identifier].upcase }
    names += net_freg_to_band_hops(@port_info.values.map {|info| info[:port_net].upcase })
    names += select_net_freq_hops(@port_info.values.map {|info| info[:port_net].upcase })
    names.uniq
end
do_next_target(next_target) click to toggle source
# File lib/peak/routing/route.rb, line 83
def do_next_target(next_target)
    if next_target != :pass
        @next_target = next_target
        throw :new_target
    end
    return
end
net_freg_to_band_hops(hops) click to toggle source
# File lib/peak/routing/route.rb, line 117
def net_freg_to_band_hops(hops)
    select_net_hops(hops).map { |hop| hop.gsub(/M\d{0,3}$/i, 'M')  }
end
select_future_hops(hops) click to toggle source
# File lib/peak/routing/route.rb, line 97
def select_future_hops(hops)
    hops.select { |hop| !hop.end_with? '*'  }
end
select_net_band_hops(hops) click to toggle source
# File lib/peak/routing/route.rb, line 102
def select_net_band_hops(hops)
    hops.select { |hop| hop =~ /\d{1,4}M$/i  }
end
select_net_freq_hops(hops) click to toggle source
# File lib/peak/routing/route.rb, line 107
def select_net_freq_hops(hops)
    hops.select { |hop| hop =~ /\d{1,4}M\d{1,3}$/i  }
end
select_net_hops(hops) click to toggle source
# File lib/peak/routing/route.rb, line 112
def select_net_hops(hops)
    hops.select { |hop| hop =~ /\d{1,4}M\d{0,3}$/i  }
end
select_next_hop(hops) click to toggle source
# File lib/peak/routing/route.rb, line 92
def select_next_hop(hops)
    select_future_hops(hops)[0]
end